# The Bro 0.8 User Manual

Vern Paxson
Lawrence Berkeley National Laboratory
and
ICSI Center for Internet Research
International Computer Science Institute
vern@icir.org

## Contents

- List of Figures
- List of Tables
- Introduction
- Getting Started
  - Running Bro
    - Building and installing Bro
    - Using Bro interactively
    - Specifying policy scripts
    - Running Bro on network traffic
    - Modifying Bro policy
    - Bro flags and run-time environment
  - Helper utilities
    - Scripts
    - The hf utility
    - The cf utility
- Values, Types, and Constants
  - Overview
    - Bro Types
    - Type Conversions
  - Booleans
    - Boolean Constants
    - Logical Operators
  - Numeric Types
    - Numeric Constants
    - Mixing Numeric Types
    - Arithmetic Operators
    - Comparison Operators
  - Enumerations
  - Strings
    - String Constants
    - String Operators
  - Patterns
    - Pattern Constants
    - Pattern Operators
  - Temporal Types
    - Temporal Constants
    - Temporal Operators
  - Port Type
    - Port Constants
    - Port Operators
  - Address Type
    - Address Constants
    - Address Operators
  - Net Type
    - Net Constants
    - Net Operators
  - Records
    - Defining records
    - Record Constants
    - Accessing Fields Using ``$''
    - Record Assignment
  - Tables
    - Declaring Tables
    - Initializing Tables
    - Table Attributes
    - Accessing Tables
    - Table Assignment
    - Deleting Table Elements
  - Sets
  - Files
  - Functions
  - Event handlers
  - The any type
- Statements and Expressions
  - Statements
  - Expressions
- Global and Local Variables
  - Overview
    - Scope
    - Modifiability
    - Typing
    - Initialization
    - Attributes
    - Refinement
- Predefined Variables and Functions
  - Predefined Variables
  - Predefined Functions
    - Run-time errors for non-existing connections
    - Run-time errors for strings with NULs
    - Functions for manipulating strings
    - Functions for manipulating time
- Analyzers and Events
  - Activating an Analyzer
    - Loading Analyzers
    - Filtering
  - General Processing Events
  - Generic Connection Analysis
    - The connection record
    - Definitions of connections
    - Generic TCP connection events
    - The tcp analyzer
    - The udp analyzer
    - Connection summaries
    - Connection functions
  - Site-specific information
    - Site variables
    - Site-specific functions
  - The hot Analyzer
    - hot variables
    - hot functions
  - The scan Analyzer
    - scan variables
    - scan functions
    - scan event handlers
  - The port-name Module
  - The mt Module
  - The log Module
  - The active Module
  - The demux Module
  - The dns Module
    - The dns_mapping record
    - dns variables
    - dns event handlers
  - The finger Analyzer
    - finger variables
    - finger event handlers
  - The frag Module
  - The hot-ids Module
  - The ftp Analyzer
    - The ftp_session_info record
    - ftp variables
    - ftp functions
    - ftp event handlers
  - The http Analyzer
    - http variables
    - http event handlers
  - The ident Analyzer
    - ident variables
    - ident event handlers
  - The login Analyzer
    - login analyzer confusion
    - login variables
    - login functions
    - login event handlers
  - The portmapper Analyzer
    - portmapper variables
    - portmapper functions
    - portmapper event handlers
  - The analy Analyzer
  - The weird Module
    - Actions for ``weird'' events
    - weird variables
    - weird functions
    - Events handled by conn_weird
    - Events handled by conn_weird_addl
    - Events handled by flow_weird
    - Events handled by net_weird
    - Events generated by the standard scripts
    - Additional handlers for ``weird'' events
  - The icmp Analyzer
  - The stepping Analyzer
  - The ssh-stepping Module
  - The backdoor Analyzer
  - The interconn Analyzer
- Missing Documentation
  - The use of prefixes
  - The tcpdump save file that Bro writes
  - The bro.init initialization file
  - Assignment operators such as +=
  - The notion of redefinition/refinement
  - The logging model
  - Timer management
  - SYN-FIN filtering
  - Split routing
  - Scan dropping
  - Operator precedence
  - Partial connections
  - Packet drops
  - The @load directive
  - Global statements
  - Inserting tables into tables
  - Demultiplexing
  - Bro init file
  - Hostnames vs. addresses
  - The hot-report script
  - Use of libpcap/BPF
  - The problem of evasion
  - Backscatter
  - Playing back traces
  - Discarders
  - Differences between this release and the previous one
  - Alert cascade
  - The need for subtyping
  - The need for CIDR masks
  - The wish list
  - Known bugs
- Bibliography
- Index

## List of Figures

1. `print-filter` prints out the `tcpdump` filter your Bro script would use and then exits.
2. Definition of the `net_stats` record.
3. Definition of `conn_id` and `connection` records.
4. Sample definition of `log_hook`
5. Definition of the `dns_mapping` record.
6. Definition of the `ftp_session_info` record
7. Example of FTP log file entries for a single FTP session.
8. Example of HTTP log file entries for a single HTTP session.

## List of Tables

1. Different types of directions for `set_contents_file`
2. TCP and UDP connection states, as stored in an `endpoint` record.
3. Summaries of connection states, as reported in `red` files.
4. Different connection states to use when calling `check_hot`.
5. Different types of confusion that `login` analyzer can report.
6. Types of calls to the RPC portmapper service.
7. Types of RPC status codes.
8. `endpoint_stats` fields for summarizing connection endpoint statistics, all of type `count`.
9. Different types of possible actions to take for ``weird'' events.

#
Introduction

Bro is an intrusion detection system that works by passively watching traffic seen on a network link. It is built around an event engine that pieces network packets into events that reflect different types of activity. Some events are quite low-level, such as the monitor seeing a connection attempt; some are specific to a particular network protocol, such as an FTP request or reply; and some reflect fairly high-level notions, such as a user having successfully authenticated during a login session.

Bro runs the events produced by the event engine through a policy script, which you (the Bro administrator) supply, though in general you will do so by using large portions of the scripts (``analyzers''; see below) that come with the Bro distribution.

You write policy scripts in ``Bro'', a specialized language geared towards network analysis in general and security analysis in particular. Bro scripts are made up of event handlers that specify what to do whenever a given event occurs. Event handlers can maintain and update global state information, write arbitrary information to disk files, generate new events, call functions (either user-defined or predefined), generate alerts that produce syslog messages, and invoke arbitrary shell commands. These latter might terminate a running connection or talk to your border router to install an ACL prohibiting traffic from a particular host, for example.

The Bro language is strongly typed and includes a bunch of types designed to aid analyzing network traffic. It also supports implicit typing, meaning that often you don't need to explicitly indicate a variable's type because Bro can figure it out from context. This feature makes the strong typing a bit less of a pain, while retaining its bug-finding benefits.

For high performance, Bro relies on use of an efficient packet filter to capture only a (hopefully small) subset of the traffic that transits the link it monitors. Related to this, Bro comes with a set of analyzers, that is, scripts for analyzing different protocols and different types of activity. In general you can pick and choose among these for which types of analysis you want to enable, and Bro will only capture traffic relating to the analyzers you choose. Thus, you can control how much work Bro has to do by the analyzers you designate, a potentially major consideration if the monitored link has a high volume of traffic.

Experience has shown that the policy scripts often require tailoring to each environment in which they're used; but if the tailoring is done by editing the analyzers supplied with the Bro distribution, you wind up with multiple copies of the analyzers, all slightly different, such that when you want to make a general change to all of them, it takes careful (and tedious) editing to correctly apply the change to all of the copies.

Consequently, Bro emphasizes the use of tables and sets of values as ways to codify policy particulars such as which hosts should generate alerts if seen engaged in various types of connections, which usernames are sensitive and should trigger alerts when used, and so on. The various analyzers are written such that you can (often) customize them by simply changing variables associated with the analyzer. Furthermore, Bro supports a notion of refining the initialization of a variable, so that, in a separate file from the one defining an analyzer, you can either (i) redefine the variable's initial value, (ii) add new elements to a given table, set or pattern, or (iii) remove elements from a given table or set. In a nutshell, refinement allows you to specify particular policies in terms of their differences from existing policies, rather than in their entirety.

You can find an overview of Bro in the paper ``Bro: A System for Detecting Network Intruders in Real-Time,'' Proceedings of the 1998 USENIX Security Symposium [Pa98], and a revised version in Computer Networks [Pa99]. A copy of the latter is included in the Bro distribution.

Using this manual. This manual is intended to provide full documentation for users of Bro, both those who wish to write Bro scripts to use Bro's existing analyzers, and those who wish to implement event engine support for new Bro analyzers. The current version of the manual is incomplete; in particular, it does not discuss the internals of the event engines, and a number of other topics have only placeholders.

The manual is organized not as a tutorial, but rather closer to a reference manual. In particular, the intent is for the index to be highly comprehensive, and to serve as one of the main tools to help you navigate through Bro's numerous features and capabilities. Accordingly, the index contains many ``redundant'' entries, that is, the same information indexed in multiple ways, to try to make it particularly easy to look up information. For example, you'll find a list of all of the predefined functions under ``predefined functions'', and also under ``functions''. There are similar entries for ``events'' and ``variables''.

The manual also includes Note:'s and Deficiency:'s that emphasize points that may be subtle or counter-intuitive, or that reflect bugs of some form. The general delineation between the two is that Note:'s discuss facets of Bro not likely to change, while Deficiency:'s will (should) eventually get fixed.

I'm very interested in feedback on whether the manual in general and the index in particular is effective, what should be added or removed from it to improve it, any errors found in the index or (of course) elsewhere in the manual, and what topics you would give the highest priority for the next revision of the manual. In addition, any contributions to the manual will be highly welcome! You'll find the source for the manual in doc/manual-src/.

The current version of the manual is organized as follows. We begin with an overview of how to get started using Bro: building and installing it, running it interactively and on live and prerecorded network traffic, and the helper utilities (scripts and programs) included in the distribution (Chapter 2).

Chapter 3 then discusses the different types, values, and constants that Bro supports. The intent is to provide you with some of the flavor of the language. In addition, later chapters use these concepts to explain things like the types associated with the arguments passed to different event handlers.

Chapter 6 lists the different variables and functions that Bro predefines. The variables generally reflect particular values that control the behavior of the event engine or reflect its status, and the functions are for the most part utilities to aid in the writing of Bro scripts.

Chapter 7 discusses the different analyzers that Bro provides. It is far and away the longest chapter, since there are a good number of analyzers, and some of them are quite rich in their analysis.

Finally, Chapter 8 briefly lists different aspects of Bro that have not yet been documented (in addition to the event engine and the Bro language itself).

#
Getting Started

This chapter gives an overview of how to get started with operating Bro: (i) compiling it, (ii) running it interactively, on live network traffic, and on recorded traces, (iii) how Bro locates the policy files it should evaluate and how to modify them, (iv) the arguments you can give it to control its operation, and (v) some helper utilities also distributed with Bro that you'll often find handy.

# Running Bro

This section discusses how to build and install Bro, running it interactively (mostly useful for building up familiarity with the policy language, not for traffic analysis), running it on live and recorded network traffic, modifying Bro policy scripts, and the different run-time flags.

##
Building and installing Bro

### Supported platforms

Bro builds on a number of types of Unix: FreeBSD, Solaris, Linux, SunOS, and Digital Unix, though not all versions. It does not build under non-Unix operating systems such as Windows NT.

###
The Bro source code distribution

You can get the latest public release of Bro from the Bro web page, http://www.icir.org/vern/bro.html. Bro is distributed as a gzip'd Unix tar archive, which you can unpack using:

> `gzcat` tar-file `| tar xf -`

or, on some Unix systems:

> `tar zxf` tar-file

This creates a subdirectory `bro-`XXX`-`version, where XXX is a tag such as `pub` for public releases and `priv` for private releases, and version reflects a version and possibly a subversion, such as `0.8a20` for version 0.8 and subversion a20.

To build Bro, change to the Bro directory and enter:

> `./configure
> make`

Fix me: Need to discuss configuration options here. `-enable-brov6`

This will compile all of the Bro sources, including a version of the BIND DNS library, version 8, which Bro uses for its non-blocking DNS lookups.

Note: For Linux systems, you may need to use the header files in the linux-include/ subdirectory included in the Bro distribution to successfully compile Bro.

###
Installing Bro

You install Bro by issuing:

> `make install`

Note: I don't actually use this functionality myself, so it does not tend to be well tested and may have bugs.

###
Tuning BPF

Bro is written using libpcap the portable packet-capture library available from `ftp:
[0]//ftp.ee.lbl.gov/
[0]libpcap.tar.Z`. While libpcap knows how to use a wide range of Unix packet filters, it far and away performs most efficiently used in conjunction with the Berkeley Packet Filter (BPF) and with BPF descendants (such as the Digital Unix packet filter). Althought BPF is available from `ftp:
[0]//ftp.ee.lbl.gov/
[0]bpf.tar.Z`, installing it involves modifying your kernel, and perhaps requires significant porting work. However, it comes as part of several operating systems, such as FreeBSD, NetBSD, and OpenBSD.

For BPF systems, you should be aware of the follwoing tuning and configuration issues:

BPF kernel support
  You need to make sure that kernel support for BPF is enabled. In addition, some systems default to configuring kernel support for only one BPF device. This often proves to be a headache because it means you cannot run more than one Bro at a time, nor can you run it at the same time as `tcpdump`.

/dev/bpf devices
  Related to the previous item, on BPF systems access to the packet filter is via special /dev/bpf devices, such as /dev/bpf0. Just as you need to make sure that the kernel's configuration supports multiple BPF devices, so to must you make sure that an equal number of device files reside in /dev/.

packet filter permissions
  On systems for which access to the packet filter is via the file system, you should consider whether you want to only allow root access, or instead create a Unix group for which you enable read access to the device file(s). The latter allows you to run Bro as a user other than root, which is strongly recommended!

large BPF buffers
  While running with BPF is often necessary for high performance, it's not necessarily sufficient. By default, BPF programs use very modest kernel buffers for storing packets, which leads to high context switch overhead as the kernel very often has to deliver packets to the user-level Bro process. Minimizing the overhead requires increasing the buffer sizes. This can make a large difference!

  Under FreeBSD, the configuration variable to increase is `debug.bpf_bufsize`, which you can set via sysctl. We recommend creating a script run at boot-up time that increases it from its small default value to something on the order of 100 KB-2 MB, depending on how fast (heavily loaded) is the link being monitored, and how much physical memory the monitor machine has at its disposal.

  Important note: some versions of libpcapave internal code that limits the maximum buffer size to 32 KB. For these systems, you should apply the patch included in the Bro distribution in the file `libpcap.patch` .

  Finally, once you have increased the buffer sizes, you should check that running Bro does indeed consume the amount of kernel memory you expect. You can do this under FreeBSD using vmstat -m and searching in the output for the summary of BPF memory. You should find that the MemUse statistic goes up by twice the buffer size for every concurrent Bro or `tcpdump` you run.2.1 The reason the increase is by twice the buffer size is because Bro uses double-buffering to avoid dropping packets when the buffer fills up.

##
Using Bro interactively

Once you've built Bro, you can run it interactively to try out simple facets of the policy language. Note that in this mode, Bro is not reading network traffic, so you cannot do any traffic analysis; this mode is simply to try out Bro language features.

You run Bro interactively by simply executing ```bro`'' without any arguments. It then reads from stdin and writes to stdout.

Try typing the following to it:

> `print "hello, world";`
> `^D` (i.e., end of file)

(The end-of-file is critical to remember. It's also a bit annoying for interactive evaluation, but reflects the fact that Bro is not actually meant for interactive use, it simply works as a side-effect of Bro's structure.)

Bro will respond by printing:

> hello, world

to stdout and exiting.

You can further declare variables and print expressions, for example:

        global a = telnet;
        print a, a > ftp;
        print www.microsoft.com;

will print

        23/tcp, T
        207.46.230.229, 207.46.230.219, 207.46.230.218

where `23/tcp` reflects the fact that `telnet` is a predefined variable whose value is TCP port 23, which is larger than TCP port 21 (i.e., `ftp`); and the DNS name www.microsoft.com currently returns the above three addresses.

You can also define functions:

        function top18bits(a: addr): addr
            {
            return mask_addr(a, 18);
            }

        print top18bits(128.3.211.7);

prints

        128.3.192.0

and even event handlers:

        event bro_done()
            {
            print "all done!";
            }

which prints ```all done!`'' when Bro exits.

## Specifying policy scripts

Usually, rather than running Bro interactively you want it to execute a policy script or a set of policy scripts. You do so by specifying the names of the scripts as command-line arguments, such as:

        bro ~/my-policy.bro ~/my-additional-policy.bro

Bro provides several mechanisms for simplifying how you specify which policies to run.

First, if a policy file doesn't exist then it will try again using `.bro` as a suffix, so the above could be specified as:

        bro ~/my-policy ~/my-additional-policy

Second, Bro consults the colon-separated search path `$BROPATH` to locate policy scripts. If your home directory was listed in `$BROPATH`, then you could have invoked it above using:

        bro my-policy my-additional-policy

Note: If you define `$BROPATH`, you must include bro-dir`/policy`, where bro-dir is where you have built or installed Bro, because it has to be able to locate bro-dir`/policy/bro.init` to initialize itself at run-time.

Third, the `@load` directive can be used in a policy script to indicate the Bro should at that point process another policy script (like C's `include` directive; see § ). So you could have in my-policy:

        @load my-additional-policy

and then just invoke Bro using:

        bro my-policy

providing you always want to load my-additional-policy whenever you load my-policy.

Note that the predefined Bro module `mt` loads almost all of the other standard Bro analyzers, so you can pull them in with simply:

        @load mt

or by invoking Bro using ```bro mt my-policy`''.

## Running Bro on network traffic

There are two ways to run Bro on network traffic: on traffic captured live by the network interface(s), and on traffic previously recorded using the `-w` flag of `tcpdump` or Bro itself.

###
Live traffic

Bro reads live traffic from the local network interface whenever you specify the `-i` flag. As mentioned below, you can specify multiple instances to read from multiple interfaces simultaneously, however the interfaces must all be of the same link type (e.g., you can't mix reading from a Fast Ethernet with reading from an FDDI link, though you can mix a 10 Mbps Ethernet interface with a 100 Mbps Ethernet).

In addition, Bro will read live traffic from the interface(s) listed in the `interfaces` variable, unless you specify the `-r` flag (and do not specify `-i`). So, for example, if your policy script contains:

        const interfaces += "sk0";
        const interfaces += "sk1";

then Bro will read from the sk0 and sk1 interfaces, and you don't need to specify `-i`.

###
Traffic traces

To run on recorded traffic, you use the `-r` flag to indicate the trace file Bro should read. As with `-i`, you can use the flag multiple times to read from multiple files; Bro will merge the packets from the files into a single packet stream based on their timestamps.

The Bro distribution includes an example trace that you can try out, example.ftp-attack.trace. If you invoke Bro using:

        setenv BRO_ID example
        bro -r example.ftp-attack.trace mt

you'll see that it generates a connection summary to stdout, a summary of the FTP sessions to `ftp.example`, a copy of what would have been real-time alerts had Bro been running on live traffic to `log.example`, and a summary of unusual traffic anomalies (none in this trace) to `weird.example`.

## Modifying Bro policy

One way to alter the policy Bro executes is of course to directly edit the scripts. When this can be avoided, however, that is preferred, and Bro provides a pair of related mechanisms to help you specify refinements to existing policies in separate files.

The first such mechanism is that you can define multiple handlers for a given event. So, for example, even though the standard `ftp` analyzer (bro-dir`/policy/ftp.bro`) defines a handler for `ftp_request`, you can define another handler if you wish in your own policy script, even if that policy script loads (perhaps indirectly, via the `mt` module) the `ftp` analyzer. When the event engine generates an `ftp_request` event, both handlers will be invoked. Deficiency: Presently, you do not have control over the order in which they are invoked; you also cannot completely override one handler with another, preventing the first from being invoked.

Second, the standard policy scripts are often written in terms of redefinable variables. For example, `ftp.bro` contains a variable `ftp_guest_ids` that defines a list of usernames the analyzer will consider to reflect guest accounts:

        const ftp_guest_ids = { "anonymous", "ftp", "guest", } &redef;

While ```const`'' marks this variables as constant at run-time, the attribute ```&redef`'' specifies that its value can be redefined.

For example, in your own script you could have:

        redef ftp_guest_ids = { "anonymous", "guest", "visitor", "student" };

instead. (Note the use of ```redef`'' rather than ```const`'', to indicate that you realize you are redefining an existing variable.)

In addition, for most types of variables you can specify incremental changes to the variable, either new elements to add or old ones to subtract. For example, you could instead express the above as:

        redef ftp_guest_ids += { "visitor", "student" };
        redef ftp_guest_ids -= "ftp";

The potential advantage of incremental refinements such as these are that if any other changes are made to `ftp.bro`'s original definition, your script will automatically inherit them, rather than replacing them if you used the first definition above (which explicitly lists all four names to include in the variable). Sometimes, however, you don't want this form of inheriting later changes; you need to decide on a case-by-case basis, though our experience is that generally the incremental approach works best.

Finally, the use of prefixes provides a way to specify a whole set of policy scripts to load in a particular context. For example, if you set `$BRO_PREFIXES` to ```dialup`'', then a load of `ftp.bro` will also load `dialup.ftp.bro` automatically (if it exists). See § for further discussion.

## Bro flags and run-time environment

### Flags

When invoking Bro, you can control its behavior using the following flags:

  [``-f filter``]
  Use filter as the `tcpdump` filter for capturing packets, rather than the combination of `capture_filter` and `restrict_filter`, or the default of ```tcp or udp`'' (§ ).

  [`-h`] Generate a help message summarizing Bro's options and environment variables, and exit.

  [``-i interface``]
  Add interface to the list of interfaces from which Bro should read network traffic (§ ). You can use this flag multiple times to direct Bro to read from multiple interfaces. You can also, or in addition, use refinements of the `interfaces` variable to specify interfaces.

  Note that if no interfaces are specified, then Bro will not read any network traffic. It does not have a notion of a ``default'' interface from which to read.

  [``-p prefix``]
  Add prefix to the list of prefixes searched by Bro when `@load`'ing a script. You can also, or in addition, use `@prefix` to specify search prefixes. See § for discussion.

  [``-r readfile``]
  Add readfile to the list of `tcpdump` save files that Bro should read. You can use this flag multiple times to direct Bro to read from multiple save files; it will merge the packets read from the different files based on their timestamps. Note that if the save files contain only packet headers and not contents, then of course Bro's analysis of them will be limited.

  Note that use of `-r` is mutually exclusive with use of `-i`. However, you can use `-r` when running scripts that refine `interfaces`, in which case the `-r` option takes precedence and Bro performs off-line analysis.

  [``-w writefile``]
  Write a `tcpdump` save file to the file writefile. Bro will record all of the packets it captures, including their contents, except as controlled by calls to `set_record_packets`.

  Note: One exception is that unless you are analyzing HTTP events (for example, by `@load`'ing the `http` analyzer), Bro does not record the contents of HTTP SYN/FIN/RST packets to the trace file. The reason for this is that HTTP FIN packets often contain a large amount of data, which is not of any interest if you are not using HTTP analysis, and due to the very high volume of HTTP traffic at many sites, removing this data can significantly reduce the size of the save file. Deficiency: Clearly, this should not be hardwired into Bro but under user control.

  Save files written using `-w` are of course readable using `-r`. Accordingly, you will generally want to use `-w` when running Bro on live network traffic so you can rerun it off-line later to understand any problems that arise, and also to experiment with the effects of changes to the policy scripts.

  You can also combine `-r` with `-w` to both read a save file(s) and write another. This is of interest when using multiple instances of `-r`, as it provides a way to merge `tcpdump` save files.

  [`-v`] Print the version of Bro and exit.

  [`-F`] Instructs Bro that it must resolve all hostnames out of its private DNS cache (§ ). If the script refers to a hostname not in the cache, then Bro exits with a fatal error.

  The point behind this option is to ensure that Bro starts quickly, rather than possibly stalling for an indeterminant amount of time resolving a hostname. Fast startup simplifies checkpointing a running Bro--you can start up a new Bro and then killing off the old one shortly after. You'd like this to occur in a manner such that there's no period during which neither Bro is watching the network (the older because you killed it off too early, the newer because it's stuck resolving hostnames).

  Deficiency: `-F` should also force Bro to load all regular expressions from its regular expression cache (§ ), but currently it doesn't do so.

  [`-O`] Turns on Bro's optimizer for improving its internal representation of the policy script. Note: Currently, the amount of improvement is modest, and there's (as always) a risk of an optimizer bug introducing errors into the execution of the script, so the optimizer is not enabled by default.

  [`-P`] Instructs Bro to prime its private DNS cache (§ ). It does so by parsing the policy scripts, but not executing them. Bro looks up each hostname's address(es) and records them in the private cache. The idea is that once `bro -P` finishes, you can then use `bro -F` to start up Bro quickly because it will read all the information it needs from the cache.

  In addition to resolving DNS lookups, Bro will also compile all of the regular expressions used in the script. Note: Such compilations can take a long time--many minutes--so it is crucial for Bro to cache the results. It does so in the file ```.bro-RE-cache.v1`'' in the user's home directory. You can delete this file whenever you want, for example to purge out old entries no longer needed.

  Note: You don't actually need to use `-P` to tell Bro to compile the regular expressions. It does so anyway whenever it encounters one that isn't already in the cache. Likewise, you don't need to use `-F` to tell Bro to use the regular expression cache--it will do so automatically whenever it can. But it's important that Bro does compilation during `-P` to help with ensuring that a subsequent invocation of Bro starts up quickly.

  Deficiency: Bro should support incrementally compiled regular expressions to avoid the expensive compilation phase altogether.

  [`-W`] Instructs Bro to activate its internal watchdog. The watchdog provides self-monitoring to enable Bro to detect if its processing is wedged.

  Bro only activates the watchdog if it is reading live network traffic. The watchdog consists of a periodic timer that fires every `WATCHDOG_INTERVAL` seconds. (Deficiency: clearly this should be a user-definable value.) At that point, the watchdog checks to see whether Bro is still working on the same packet as it was the last time the watchdog expired. If so, then the watchdog logs this fact along with some information regarding when Bro began processing the current packet and how many events it processed after handling the packet. Finally, it prints the packet drop information for the different interfaces Bro was reading from, and aborts execution.

### Run-time environment

Bro is also sensitive to the following environment variables:

  [`$BROPATH`] A colon-separated list of directories that Bro searches whenever you `@load` a policy file. It loads the first instance it finds (though see `$BRO_PREFIXES` for how a single `@load` can lead to Bro loading multiple files).

  Default: if you don't set this variable, then Bro uses the path

          .:policy:policy/local:/usr/local/lib/bro

  That is, the current directory, any policy/ and policy/local/ subdirectories, and /usr/local/lib/bro/.

  [`$BRO_PREFIXES`] A colon-separate lists of prefixes that Bro should apply to each name in a `@load` directive. For a given prefix and load-name, Bro constructs the filename:

  > prefix`.`load-name`.bro`

  (where it doesn't add `.bro` if load-name already ends in `.bro`). It then searches for the filename using `$BROPATH` and loads it if its found. Furthermore, it repeats this process for all of the other prefixes (left-to-right), and loads each file it finds for the different prefixes. Note: Bro also first attempts to load the filename without any prefix at all. If this load fails, then Bro exits with an error complaining that it can't open the given `@load` file.

  For example, if you set `$BRO_PREFIXES` to:

          mysite:mysite.wan

  and then issue ```@load` `ftp`'', Bro will attempt to load each of the following scripts in the following order:

          ftp.bro
          mysite.ftp.bro
          mysite.wan.ftp.bro

  Default: if you don't specify a value for `$BRO_PREFIXES`, it defaults to empty, and for the example above Bro would only attempt to `@load` `ftp.bro`.

# Helper utilities

## Scripts

Documentation missing.

##
The hf utility

The hf utility reads text on stdin and attempts to convert any ``dotted quads'' it sees to hostnames. It is very convenient for running on Bro log files to generate human-readable forms. See the manual page included with the distribution for details.

##
The cf utility

The cf utility reads Unix timestamps at the beginning of lines on stdin and converts them to human-readable form. For example, for the input line:

    972499885.784104 #26 131.243.70.68/1899 > 64.55.26.206/ftp start

it will generate:

    Oct 25 11:51:25 #26 131.243.70.68/1899 > 64.55.26.206/ftp start

It takes two flags:

`-l`
  specifies the long human-readable form, which includes the year. For example, on the above input, the output would instead be:

      Oct 25 11:51:25 2000 #26 131.243.70.68/1899 > 64.55.26.206/ftp start

`-s`
  specifies strict checking to ensure that the number at the beginning of a line is a plausible timestamp: it must have at least 9 digits, at most one decimal, and must have a decimal if there are 10 or more digits.

  Without `-s`, an input like:

      131.243.70.68 > 64.55.26.206

  generates the output:

      Dec 31 16:02:11 > 64.55.26.206

  which, needless to say, is not very helpful. Deficiency: It seems clear that `-s` should be the default behavior.

#
Values, Types, and Constants

# Overview

We begin with an overview of the types of values supported by Bro, giving a brief description of each type and introducing the notions of type conversion and type inference. We discuss each type in detail in § 3.2-§ 3.17 below.

## Bro Types

There are 18 types of values in the Bro type system:

- `bool` for Booleans;

- `count`, `int`, and `double` types, collectively called numeric, for arithmetic and logical operations, and comparisons;

- `enum` for enumerated types similar to those in C;

- `string`, character strings that can be used for comparisons and to index tables and sets;

- `pattern`, regular expressions that can be used for pattern matching;

- `time` and `interval`, for absolute and relative times, collectively termed temporal;

- `port`, a TCP or UDP port number;

- `addr`, an IP address;

- `net`, a network prefix;

- `record`, a collection of values (of possibly different types), each of which has a name;

- `table`, an associative array, indexed by tuples of scalars and yielding values of a particular type;

- `set`, a collection of tuples-of-scalars, for which a particular tuple's membership can be tested;

- `file`, a disk file to write or append to;

- `function`, a function that when called with a list of values (arguments) returns a value;

- `event`, an event handler that is invoked with a list of values (arguments) any time an event occurs.

Every value in a Bro script has one of these types. For most types there are ways of specifying constants representing values of the type. For example, `2.71828` is a constant of type `double`, and `80/tcp` is a constant of type `port`. The discussion of types in § 3.2-§ 3.17 below includes a description of how to specify constants for the types.

Finally, even though Bro variables have static types, meaning that their type is fixed, often their type is inferred from the value to which they are initially assigned when the variable is declared. For example,

        local a = "hi there";

fixes `a`'s type as `string`, and

        local b = 6;

sets `b`'s type to `count`. See § for further discussion.

##
Type Conversions

Some types will be automatically converted to other types as needed. For example, a `count` value can always be used where a `double` value is expected. The following:

        local a = 5;
        local b = a * .2;

creates a local variable `a` of type `count` and assigns the `double` value `1.0` to `b`, which will also be of type `double`. Automatic conversions are limited to converting between numeric types. The rules for how types are converted are given below.

#
Booleans

The `bool` type reflects a value with one of two possible meanings: true or false.

##
Boolean Constants

There are two `bool` constants: `T` and `F`. They represent the values of ``true" and ``false", respectively.

##
Logical Operators

Bro supports three logical operators: `&&`, `||`, and `!` are Boolean ``and,'' ``or,'' and ``not,'' respectively. `&&` and `||` are ``short circuit'' operators, as in C: they evaluate their right-hand operand only if needed.

The `&&` operator returns `F` if its first operand evaluates to false, otherwise it evaluates its second operand and returns `T` if it evaluates to true. The `||` operator evaluates its first operand and returns `T` if the operand evaluates to true. Otherwise it evaluates its second operand, and returns `T` if it is true, `F` if false.

The unary `!` operator returns the boolean negation of its argument. So, `! T` yields `F`, and `! F` yields `T`.

The logical operators are left-associative. The `!` operator has very high precedence, the same as unary `+` and `-`; see § 3.3.3 and § 8.11. The `||` operator has precedence just below `&&`, which in turn is just below that of the comparison operators (see § ).

# Numeric Types

`int`, `count`, and `double` types should be familiar to most programmers as integer, unsigned integer, and double-precision floating-point types.

These types are referred to collectively as numeric. Numeric types can be used in arithmetic operations (see § 3.3.3 below) as well as in comparisons (§ ).

##
Numeric Constants

`count` constants are just strings of digits: `1234` and `0` are examples.

`integer` constants are strings of digits preceded by a `+` or `-` sign: `-42` and `+5` for example. Because digit strings without a sign are of type `count`, occasionally you need to take care when defining a variable if it really needs to be of type `int` rather than `count`. Because of type inferencing (§ ), a definition like:

        local size_difference = 0;

will result in `size_difference` having type `count` when `int` is what's instead needed (because, say, the size difference can be negative). This can be resolved either by using an `int` constant in the initialization:

        local size_difference = +0;

or explicitly indicating the type:

        local size_difference: int = 0;

You write floating-point constants in the usual ways, a string of digits with perhaps a decimal point and perhaps a scale-factor written in scientific notation. Optional `+` or `-` signs may be given before the digits or before the scientific notation exponent. Examples are `-1234.`, `-1234e0`, `3.14159`, and `.003e-23`. All floating-point constants are of type `double`.

##
Mixing Numeric Types

You can freely intermix numeric types in expressions. When intermixed, values are promoted to the ``highest" type in the expression. In general, this promotion follows a simple hierarchy: `double` is highest, `int` comes next, and `count` is lowest. (Note that `bool` is not a numeric type.)

##
Arithmetic Operators

For doing arithmetic, Bro supports `+`, `-`, `*`, `/`, and `%`#4768#>In general, binary operators evaluate their operands after converting them to the higher type of the two and return a result of that type. However, subtraction of two `count` values yields an `int` value. Division is integral if its operands are `count` and/or `int`.

`+` and `-` can also be used as unary operators. If applied to a `count` type, they yield an `int` type.

`%` computes a modulus, defined in the same way as in the C language. It can only be applied to `count` or `int` types, and yields `count` if both operands are `count` types, otherwise `int`.

Binary `+` and `-` have the lowest precedence, `*`, `/`, and `%` have equal and next highest precedence. The unary `+` and `-` operators have the same precedence as the `!` operator (§ ). See § , for a table of the precedence of all Bro operators.

All arithmetic operators associate from left-to-right.

##
Comparison Operators

Bro provides the usual comparison operators: `==`, `!=`, `<`, `<=`, `>`, and `>=`. They each take two operands, which they convert to the higher of the two types (see § ). They return a `bool` corresponding to the comparison of the operands. For example,

        3 < 3.000001

yields true.

The comparison operators are all non-associative and have equal precedence, just below that of the `in` operator and just above that of the logical `&&` operator. See § , for a general discussion of precedence.

#
Enumerations

Enumerations allow you to specify a set of related values that have no further structure, similar to `enum` types in C. For example:

        type color: enum { Red, White, Blue, };

defines the values `Red`, `White`, and `Blue`. A variable of type `color` holds one of these values. Note that `Red` et al have global scope. You cannot define a variable or type with those names. (Also note that, as usual, the comma after `Blue` is optional.)

The only operations allowed on enumerations are comparisons for equality. Unlike C enuemrations, they do not have values or an ordering associated with them.

You can extend the set of values in an enumeration using `redef enum identifier += { name-list }`:

        redef enum color += { Black, Yellow };

#
Strings

The `string` type holds character-string values, used to represent and manipulate text.

##
String Constants

You create string constants by enclosing text within double (`"`) quotes. A backslash character (`\`) introduces an escape sequence. The following ANSI C escape sequences are recognized: `\a` yields an alert (bell) character, `\b` yields a backspace character, `\f` yields a formfeed character, `\n` yields a newline character, `\r` yields a carriage return character, `\t` a tab character, `\`octal-digits the 8-bit ASCII character with code octal-digits, and `\x` hex-digits the 8-bit ASCII character with code hex-digits. Bro string constants currently cannot be continued across multiple lines by escaping newlines in the input. This may change in the future. Any other character following a `\` is passed along literally.

Unlike with C, strings are represented internally as a count and a vector of bytes, rather than a NUL-terminated series of bytes. This difference is important because NULs can easily be introduced into strings derived from network traffic, either by the nature of the application, inadvertently, or maliciously by an attacker attempting to subvert the monitor. An example of the latter is sending the following to an FTP server:

        USER nice\0USER root

where ```\0`'' represents a NUL. Depending on how it is written, the FTP application receiving this text might well interpret it as two separate commands, ```USER nice`'' followed by ```USER root`''. But if the monitoring program uses NUL-terminated strings, then it will effectively see only ```USER nice`'' and have no opportunity to detect the subversive action.

Note that Bro string constants are automatically NUL-terminated.

Note: While Bro itself allows NULs in strings, their presence in arguments to many Bro functions results in a run-time error, as often their presence (or, conversely, lack of a NUL terminator) indicates some sort of problem (particularly for arguments that will be passed to C functions). See § for discussion.

## String Operators

Currently the only string operators provided are the comparison operators discussed in § and pattern-matching as discussed in § . These operators perform character by character comparisons based on the native character set, usually ASCII.

Some functions for manipulating strings are also available. See § .

#
Patterns

The `pattern` type holds regular-expression patterns, which can be used for fast text searching operations.

##
Pattern Constants

You create pattern constants by enclosing text within forward slashes (`/`). The syntax is the same as for the flex version of the lex utility. For example,

        /foo|bar/

specifies a pattern that matches either the text ``foo'' or the text ``bar'';

        /[a-zA-Z0-9]+/

matches one or more letters or digits, as will

        /[[:alpha:][:digit:]]+/

or

        /[[:alnum:]]+/

and the pattern

        /^rewt.*login+/

matches any string with the text ``rewt'' at the beginning of a line followed somewhere later in the line by the text ``login''.

You can create disjunctions (patterns the match any of a number of alternatives) both using the ```|`'' regular expression operator directly, as in the first example above, or by using it to join multiple patterns. So the first example above could instead be written:

        /foo/ | /bar/

This form is convenient when constructing large disjunctions because it's easier to see what's going on.

Note that the speed of the regular expression matching does not depend on the complexity or size of the patterns, so you should feel free to make full use of the expressive power they afford.

You can assign `pattern` values to variables, hold them in tables, and so on. So for example you could have:

        global address_filters: table[addr] of pattern = {
            [128.3.4.4] = /failed login/ | /access denied/,
            [128.3.5.1] = /access timeout/
        };

and then could test, for example:

        if ( address_filters[c$id$orig_h] in msg )
            skip_the_activity();

Note though that you cannot use create patterns dynamically. this form (or any other) to create dynamic

##
Pattern Operators

There are two types of pattern-matching operators: exact matching and embedded matching.

###
Exact Pattern Matching

Exact matching tests for a string entirely matching a given pattern. You specify exact matching by using the `==` equality relational with one `pattern` operand and one `string` operand (order irrelevant). For example,

        "foo" == /foo|bar/

yields true, while

        /foo|bar/ == "foobar"

yields false. The `!=` operator is the negation of the `==` operator, just as when comparing strings or numerics.

Note that for exact matching, the `^` (anchor to beginning-of-line) and `$` (anchor to end-of-line) regular expression operators are redundant: since the match is exact, every pattern is implicitly anchored to the beginning and end of the line.

###
Embedded Pattern Matching

Embedded matching tests whether a given pattern appears anywhere within a given string. You specify embedded pattern matching using the `in` operator. It takes two operands, the first (which must appear on the left-hand side) of type `pattern`, the second of type `string`. For example,

        /foo|bar/ in "foobar"

yields true, as does

        /oob/ in "foobar"

but

        /^oob/ in "foobar"

does not, since the text ``oob'' does not appear the beginning of the string ``foobar''. Note, though, that the `$` regular expression operator (anchor to end-of-line) is not currently supported, so:

        /oob$/ in "foobar"

currently yields true. This is likely to change in the future.

Finally, the `!in` operator yields the negation of the `in` operator.

#
Temporal Types

Bro supports types representing absolute and relative times with the `time` and `interval` types, respectively.

##
Temporal Constants

There is currently no way to specify an absolute time as a constant (though see the `current_time` and `network_time` functions in § ). You can specify `interval` constants, however, by appending a time unit after a numeric constant. For example,

        3.5 min

denotes 210 seconds. The different time units are `usec`, `sec`, `min`, `hr`, and `day`, representing microseconds, seconds, minutes, hours, and days, respectively. The whitespace between the numeric constant and the unit is optional, and the letter ``s'' may be added to pluralize the unit (this has no semantic effect). So the above example could also be written:

        3.5mins

or

        150 secs

##
Temporal Operators

You can apply arithmetic and relational operators to temporal values, as follows.

###
Temporal Negation

The unary `-` operator can be applied to an `interval` value to yield another `interval` value. For example,

        - 12 hr

represents ``twelve hours in the past.''

###
Temporal Addition

Adding two `interval` values yields another `interval` value. For example,

        5 sec + 2 min

yields 125 seconds. Adding a `time` value to an `interval` yields another `time` value.

###
Temporal Subtraction

Subtracting a `time` value from another `time` value yields an `interval` value, as does subtracting an `interval` value from another `interval`, while subtracting an `interval` from a `time` yields a `time`.

###
Temporal Multiplication

You can multiply an `interval` value by a numeric value to yield another `interval` value. For example,

       5 min * 6.5

yields 1,950 seconds. `time` values cannot be scaled by multiplication or division.

###
Temporal Division

You can also divide an `interval` value by a numeric value to yield another `interval` value. For example,

       5 min / 2

yields 150 seconds. Furthermore, you can divide one `interval` value by another to yield a `double`. For example,

       5 min / 30 sec

yields 10.

###
Temporal Relationals

You may compare two `time` values or two `interval` values for equality, and also for ordering, where times or intervals further in the future are considered larger than times or intervals nearer in the future, or in the past.

#
Port Type

The `port` type corresponds to a TCP or UDP port number. TCP and UDP ports are distinct. Thus, a value of type `port` can hold either a TCP or a UDP port, but at any given time it is holding exactly one of these.

##
Port Constants

There are two forms of `port` constants. The first consists of an unsigned integer followed by either ```/tcp`'' or ```/udp`.'' So, for example, ```80/tcp`'' corresponds to TCP port 80 (the HTTP protocol used by the World Wide Web). The second form of constant is specified using a predefined identifier, such as ```http`'', equivalent to ```80/tcp`.'' These predefined identifiers are simply `const` variables defined in the Bro initialization file (§ ), such as:

        const http = 80/tcp;

##
Port Operators

The only operations that can be applied to `port` values are relationals. You may compare them for equality, and also for ordering. For example,

         20/tcp < telnet

yields true because `telnet` is a predefined constant set to `23/tcp`.

UDP ports are considered larger than TCP ports, i.e., ```0/udp`'' is larger than ```65535/tcp`''.

#
Address Type

Another networking type provided by Bro is `addr`, corresponding to an IP address. The only operations that can be performed on them are comparisons for equality or inequality (also, a built-in function provides masking, as discussed below).

When configuring the Bro distribution, if you specify `-enable-brov6` then Bro will be built to support both IPv4 and IPv6 addresses, and an `addr` can hold either. Otherwise, addresses are restricted to IPv4.

##
Address Constants

Constants of type `addr` have the familiar ``dotted quad'' format, , where the all lie between 0 and 255. If you have configured for IPv6 support as discussed above, then you can also use the colon-separated hexadecimal form described in [RFC2373].

Often more useful are hostname constants. There is no Bro type corresponding to Internet hostnames. Because hostnames can correspond to multiple IP addresses, you quickly run into ambiguities if comparing one hostname with another. Bro does, however, support hostnames as constants. Any series of two or more identifiers delimited by dots forms a hostname constant, so, for example, ```lbl.gov`'' and ```www.microsoft.com`'' are both hostname constants (the latter, as of this writing, corresponds to 5 distinct IP addresses). The value of a hostname constant is a `list` of `addr` containing one or more elements. These lists (as with the lists associated with certain `port` constants, discussed above) cannot be used in Bro expressions; but they play a central role in initializing Bro `table`'s and `set`'s.

##
Address Operators

The only operations that can be applied to `addr` values are comparisons for equality or inequality, using `==` and `!=`. However, you can also operate on `addr` values using `mask_addr` to mask off lower address bits, and `to_net` to convert an `addr` to a `net` (see below).

#
Net Type

Related to the `addr` type is `net`. `net` values hold address prefixes. Historically, the IP address space was divided into different classes of addresses, based on the uppermost components of a given address: class A spanned the range 0.0.0.0 to 127.255.255.255; class B from 128.0.0.0 to 191.255.255.255; class C from 192.0.0.0 to 223.255.255.255; class D from 224.0.0.0 to 239.255.255.255; and class E from 240.0.0.0 to 255.255.255.255. Addresses were allocated to different networks out of either class A, B, or C, in blocks of , , and addresses, respectively.

Accordingly, `net` values hold either an 8-bit class A prefix, a 16-bit class B prefix, a 24-bit class C prefix, or a 32-bit class D ``prefix'' (an entire address). Values for class E prefixes are not defined (because no such addresses are currently allocated, and so shouldn't appear in other than clearly-bogus packets).

Today, address allocations come not from class A, B or C, but instead from CIDR blocks (CIDR = Classless Inter-Domain Routing), which are prefixes between 1 and 32 bits long in the range 0.0.0.0 to 223.255.255.255. Deficiency: Bro should deal just with CIDR prefixes, rather than old-style network prefixes. However, these are more difficult to implement efficiently for table searching and the like; hence currently Bro only supports the easier-to-implement old-style prefixes. Since these don't match current allocation policies, often they don't really fit an address range you'll want to describe. But for sites with older allocations, they do, which gives them some basic utility.

In addition, Deficiency: IPv6 has no notion of old-style network prefixes, only CIDR prefixes, so the lack of support of CIDR prefixes impairs use of Bro to analyze IPv6 traffic.

##
Net Constants

You express constants of type `net` in one of two forms, either:

or

where the all lie between 0 and 255. The first of these corresponds to class B prefixes (note the trailing ```.`'' that's required to distinguish the constant from a floating-point number), and the second to class C prefixes. Deficiency: There's currently no way to specify a class A prefix.

##
Net Operators

The only operations that can be applied to `net` values are comparisons for equality or inequality, using `==` and `!=`.

#
Records

A `record` is a collection of values. Each value has a name, referred to as one of the record's fields, and a type. The values do not need to have the same type, and there is no restriction on the allowed types (i.e., each field can be any type).

##
Defining records

A definition of a record type has the following syntax:

> `record {` field `}`

(that is, the keyword `record` followed by one-or-more field's enclosed in braces), where a field has the syntax:

> identifier `:` type field-attributes `;` identifier `:` type field-attributes `,`

Each field has a name given by the identifier (which can be the same as the identifier of an existing variable or a field in another record). Field names must follow the same syntax as that for Bro variable names (see § ), namely they must begin with a letter or an underscore (```_`'') followed by zero or more letters, underscores, or digits. Bro reserved words such as `if` or `event` cannot be used for field names. Field names are case-sensitive.

Each field holds a value of the given type. We discuss the optional field-attributes below. Finally, you can use either a semicolon or a comma to terminate the definition of a record field.

For example, the following record type:

        type conn_id: record {
            orig_h: addr;  # Address of originating host.
            orig_p: port;  # Port used by originator.
            resp_h: addr;  # Address of responding host.
            resp_p: port;  # Port used by responder.
        };

is used throughout Bro scripts to denote a connection identifier by specifying the connections originating and responding addresses and ports. It has four fields: `orig_h` and `resp_h` of type `addr`, and `orig_p` of `resp_p` of type `port`.

##
Record Constants

You can initialize values of type `record` using either assignment from another, already existing `record` value; or element-by-element; or using a record constructor.

In a Bro function or event handler, we could declare a local variable the `conn_id` type given above:

        local id: conn_id;

and then explicitly assign each of its fields:

        id$orig_h = 207.46.138.11;
        id$orig_p = 31337/tcp;
        id$resp_h = 207.110.0.15;
        id$resp_p = 22/tcp;

Deficiency: One danger with this initialization method is that if you forget to initialize a field, and then later access it, you will crash Bro.

Or we could use:

        id = [$orig_h = 207.46.138.11, $orig_p = 31337/tcp,
              $resp_h = 207.110.0.15, $resp_p = 22/tcp];

This second form is no different from assigning a `record` value computed in some other fashion, such as the value of another variable, a table element, or the value returned by a function call. Such assignments must specify all of the fields in the target (i.e., in `id` in this example), unless the missing field has the or attribute.

##
Accessing Fields Using ```$`''

You access and assign record fields using the ```$`'' (dollar-sign) operator. As indicated in the example above, for the record `id` we can access its `orig_h` field using:

        id$orig_h

which will yield the `addr` value `207.46.138.11`.

##
Record Assignment

You can assign one record value to another using simple assignment:

        local a: conn_id;
        ...
        local b: conn_id;
        ...
        b = a;

Doing so produces a shallow copy. That is, after the assignment, `b` refers to the same record as does `a`, and an assignment to one of `b`'s fields will alter the field in `a`'s value (and vice versa for an assignment to one of `a`'s fields). However, assigning again to `b` itself, or assigning to `a` itself, will break the connection.

Deficiency: Bro lacks a mechanism for specifying a deep copy, in which no linkage is connected between `b` and `a`. Consequently, you must be careful when assigning records to ensure you account for the shallow-copy semantics.

You can also assign to a record another record that has fields with the same names and types, even if they come in a different order. For example, if you have:

        local b: conn_id;
        local c: record {
            resp_h: addr, orig_h: addr;
            resp_p: port, orig_p: port;
        };

then you can assign either `b` to `c` or vice versa.

You could not, however, make the assignment (in either direction) if you had:

        local b: conn_id;
        local c: record {
            resp_h: addr, orig_h: addr;
            resp_p: port, orig_p: port;
            num_alerts: count;
        };

because the field `num_alerts` would either be missing or excess.

However, when declaring a record you can associate attributes with the fields. The relevant ones are `&optional`, which indicates that when assigning to the record you can omit the field, and `&default` `= expr`, which indicates that if the field is missing, then a reference to it returns the value of the expression expr. So if instead you had:

        local b: conn_id;
        local c: record {
            resp_h: addr, orig_h: addr;
            resp_p: port, orig_p: port;
            num_alerts: count &optional;
        };

then you could execute `c = b` even though `num_alerts` is missing from `b`. You still could not execute `b = c`, though, since in that direction, `num_alerts` is an extra field (regardless of whether it has been assigned to or not--the error is a type-checking error, not a run-time error).

The same holds for:

        local b: conn_id;
        local c: record {
            resp_h: addr, orig_h: addr;
            resp_p: port, orig_p: port;
            num_alerts: count &default = 0;
        };

I.e., you could execute `c = b` but not `b = c`. The only difference between this example and the previous one is that for the previous one, access to `c$num_alerts` without having first assigned to it results in a run-time error, while in the second, it yields `0`.

You can test for whether a record field exists using the `?$` operator.

Finally, all of the rules for assigning records also apply when passing a record value as an argument in a function call or an event handler invocation.

#
Tables

`table`'s provide associative arrays: mappings from one set of values to another. The values being mapped are termed the index (or indices, if they come in groups of more than one) and the results of the mapping the yield.

Tables are quite powerful, and indexing them is very efficient, boiling down to a single hash table lookup. So you should take advantage of them whenever appropriate.

##
Declaring Tables

You declare tables using the following syntax:

> `table [` type `] of` type

where type is one or more types, separated by commas.

The indices can be of the following scalar types: numeric, temporal, enumerations, `string`, `port`, `addr`, or `net`. The yield can be of any type. So, for example:

        global a: table[count] of string;

declares `a` to be a table indexed by a `count` value and yielding a `string` value, similar to a regular array in a language like C. The yield type can also be more complex:

        global a: table[count] of table[addr, port] of conn_id;

declares `a` to be a table indexed by `count` and yielding another table, which itself is indexed by an `addr` and a `port` to yield a `conn_id` record.

This second example illustrates a multi-dimensional table, one indexed not by a single value but by a tuple of values.

##
Initializing Tables

You initialize tables by enclosing a set of initializers within braces. Each initializer looks like:

> `[` expr-list `] =` expr

where expr-list is a comma-separated list of expressions corresponding to an index of the table (so, for a table indexed by `count`, for example, this would be a single expression of type `count`) and expr is the yield value to assign to that index.

For example,

        global a: table[count] of string = {
            [11] = "eleven",
            [5] = "five",
        };

initializes the table `a` to have two elements, one indexed by `11` and yielding the string `"eleven"` and the other indexed by `5` and yielding the string `"five"`. (Note the comma after the last list element; it is optional, similar to how C allows final commas in declarations.)

You can also group together a set of indices together to initialize them to the same value:

        type HostType: enum { DeskTop, Server, Router };
        global a: table[addr] of HostType = {
            [[155.26.27.2, 155.26.27.8, 155.26.27.44]] = Server,
        };

is equivalent to:

        type HostType: enum { DeskTop, Server, Router };
        global a: table[addr] of HostType = {
            [155.26.27.2] = Server,
            [155.26.27.8] = Server,
            [155.26.27.44] = Server,
        };

This mechanism also applies to hostnames, which can be used in table initializations for any indices of type `addr`. For example, if `www.my-server.com` corresponded to the addresses 155.26.27.2 and 155.26.27.44, then the above could be written:

        global a: table[addr] of HostType = {
            [[www.my-server.com, 155.26.27.8]] = Server,
        };

and if it corresponded to all there, then:

        global a: table[addr] of HostType = {
            [www.my-server.com] = Server,
        };

You can also use multiple index groupings across different indices:

        global access_allowed: table[addr, port] of bool = {
            [www.my-server.com, [21/tcp, 80/tcp]] = T,
        };

is equivalent to:

        global access_allowed: table[addr, port] of bool = {
            [155.26.27.2, 21/tcp] = T,
            [155.26.27.2, 80/tcp] = T,
            [155.26.27.8, 21/tcp] = T,
            [155.26.27.8, 80/tcp] = T,
            [155.26.27.44, 21/tcp] = T,
            [155.26.27.44, 80/tcp] = T,
        };

Fix me: add example of cross-product initialization of sets

##
Table Attributes

When declaring a table, you can specify a number of attributes that affect its operation:

  [`&default`] Specifies a value to yield when an index does not appear in the table. Syntax:

  > `&default = expr`

  expr can have one of two forms. If it's type is the same as the table's yield type, then expr is evaluated and returned. If it's type is a `function` with arguments whose types correspond left-to-right with the index types of the table, and which returns a type the same as the yield type, then that function is called with the indices that yielded the missing value to compute the default value.

  For example:

          global a: table[count] of string &default = "nothing special";

  will return the string `"nothing special"` anytime `a` is indexed with a `count` value that does not appear in `a`.

  A more dynamic example:

          function nothing_special(): string
              {
              if ( panic_mode )
                  return "look out!";
              else
                  return "nothing special";
              }

          global a: table[count] of string &default = nothing_special;

  An example of using a function that computes using the index:

          function make_pretty(c: count): string
              {
              return fmt("**%d**", c);
              }

          global a: table[count] of string &default = make_pretty;

  [`&create_expire`] Specifies that elements in the table should be automatically deleted after a given amount of time has elapsed since they were first entered into the table. Syntax:

  > `&create_expire = expr`

  where expr is of type `interval`.

  [`&read_expire`] The same as `&create_expire` except the element is deleted when the given amount of time has lapsed since the last time the element was accessed from the table.

  [`&write_expire`] The same as `&create_expire` except the element is deleted when the given amount of time has lapsed since the last time the element was entered or modified in the table.

  [`&expire_func`] Specifies a function to call when an element is due for expression because of `&create_expire`, `&read_expire`, or `&write_expire`. Syntax:

  > `&expire_func = expr`

  expr must be a function that takes an argument with the same type as the table's yield type and returns an `interval` value. The `interval` indicates for how much longer the element should remain in the table; returning `0 secs` or a negative value instructs Bro to go ahead and delete the element.

  Deficiency: There should be a version of `&expire_func` that is passed the index of the element as well as its yield value.

You specify multiple attributes by listing one after the other, without commas between them:

        global a: table[count] of string &default="foo" &write_expire=5sec;

Note that you can specify each type of attribute only once. You can, however, specify more than one of `&create_expire`, `&read_expire`, and `&write_expire`. In that case, whenever any of the corresponding timers expires, the element will be deleted.

##
Accessing Tables

As usual, you access the values in tables by indexing them with a value (for a single index) or list of values (multiple indices) enclosed in `[]`'s. Deficiency: Presently, when indexing a multi-dimensional table you must provide all of the relevant indices; you can't leave one out in order to extract a sub-table.

You can also index arrays using `record`'s, providing the record is comprised of values whose types match that of the table's indices. (Any record fields whose types are themselves records are recursively unpacked to effect this matching.) For example, if we have:

        local b: table[addr, port] of conn_id;
        local c = 131.243.1.10;
        local d = 80/tcp;

then we could index `b` using `b[c, d]`, but if we had:

        local e = [$field1 = c, $field2 = d];

we could also index it using `a[d]`

You can test whether a table holds a given index using the `in` operator. For example:

        [131.243.1.10, 80/tcp] in b

or

        e in b

per the examples above. In addition, if the table has only a single index (not multi-dimensional), then you can omit the `[]`'s:

        local active_connections: table[addr] of conn_id;
        ...
        if ( 131.243.1.10 in active_connections )
            ...

##
Table Assignment

An indexed can be the target of an assignment:

        b[131.243.1.10, 80/tcp] = c$id;

You can also assign to an entire table. For example, suppose we have the global:

        global active_conn_count: table[addr, port] of count;

then we could later clear the contents of the table using:

        local empty_table: table[addr, port] of count;
        active_conn_count = empty_table;

Here the first statement declares a local variable `empty_table` with the same type as `active_conn_count`. Since we don't initialize the table, it starts out empty. Assigning it to `active_conn_count` then replaces the value of `active_conn_count` with an empty table. Note: As with `record`'s, assigning `table` values results in a shallow copy.

In addition to directly accessing an element of a table by specifying its index, you can also loop over all of the indices in a table using the `for` statement.

##
Deleting Table Elements

You can remove an individual element from a table using the `delete` statement:

        delete active_host[c$id];

will remove the element in `active_host` corresponding to the connection identifier `c$id` (which is a `conn_id` record). If the element isn't present, nothing happens.

#
Sets

Sets are very similar to tables. The principle difference is that they are simply a collection of indices; they don't yield any values. You declare tables using the following syntax:

> `set [` type `]`

where, as with `table`s, type is one or more scalar types (or records), separated by commas.

You initialize sets listing their elements in braces:

        global a = { 21/tcp, 23/tcp, 80/tcp, 443/tcp };

which implicitly types `a` as a `set[port]` and then initializes it to contain the given 4 `port` values.

For multiple indices, you enclose each set of indices in brackets:

        global b = { [21/tcp, "ftp"], [23/tcp, "telnet"], };

which implicitly `b` as `set[port, string]` and then initializes it to contain the given two elements. (As with tables, the comma after the last element is optional.)

As with tables, you can group together sets of indices:

        global c = { [21/tcp, "ftp"], [[80/tcp, 8000/tcp, 8080/tcp], "http"], };

initializes `c` to contain 4 elements.

Also as with tables, you can use the `&create_expire`, `&read_expire`, and `&write_expire` attributes to control the automatic expiration of elements in a set. Deficiency: However, the `&expire_func` attribute is not currently supported.

You can test for whether a particular member is in a set using the `in` operator, as with tables. You add elements using the `add` statement:

        add c[443/tcp, "https"];

and can remove them using the `delete` statement:

        add d[21/tcp, "ftp"];

Also, as with tables, you can assign to the entire set, which assigns a shallow copy.

Finally, as with tables, you can loop over all of the indices in a set using the `for` statement.

#
Files

Deficiency: Bro currently supports only a very simple notion of files. You can only write to files, you can't read from them: and files are essentially untyped--the only values you can write to them are `string`'s or values that can be converted to `string`.

You declare `file` variables simply as type `file`:

        global f: file;

You can create values of type `file` by using the `open` function:

        f = open("suspicious_info.log");

will create (or recreate, if it already exists) the file suspicious_info.log and open it for writing. You can also use `open_for_append` to append to an existing file (or create a new one, if it doesn't exist).

You write to files using the `print` statement:

        print f, 5 * 6;

will print the text `30` to the file corresponding to the value of `f`.

There is no restriction regarding how many files you can have open at a given time. In particular, even if your system has a limit imposed by `RLIMIT_NOFILE`s set by the system call `setrlimit`. If, however, you want to to close a file, you can do so using `close`, and you can test whether a file is open using `active_file`.

Finally, you can control whether a file is buffered using `set_buf`, and can flush the buffers of all open files using `flush_all`.

#
Functions

You declare a Bro `function` type using:

> `function (` argument `)` [ ``:` type` ]

where argument is a (possibly empty) comma-separated list of arguments, and the final ```:` type'' declares the return type of the function. It is optional; if missing, then the function does not return a value.

Each argument is declared using:

> param-name `:` type

So, for example:

        function(a: addr, p: port): string

corresponds to a function that takes two parameters, `a` of type `addr` and `p` of type `port`, and returns a value of type `string`.

You could furthermore declare:

        global generate_id: function(a: addr, p: port): string;

to define `generate_id` as a variable of this type. Note that the declaration does not define the body of the function, and, indeed, `generate_id` could have different function bodies at different times, by assigning different function values to it.

When defining a function including its body, the syntax is slightly different:

> `function` func-name `(` argument `)` [ ``:` type` ] `{` statement `}`

That is, you introduce func-name, the name of the function, between the keywork `function` and the opening parenthesis of the argument list, and you list the statements of the function within braces at the end.

For the previous example, we could define its body using:

        function generate_id(a: addr, p: port): string
            {
            if ( a in local_servers )
                # Ignore port, they're always the same.
                return fmt("server %s", a);

            if ( p < 1024/tcp )
                # Privileged port, flag it.
                return fmt("%s/priv-%s", a, p);

            # Nothing special - default formatting.
            return fmt("%s/%s", a, p);
            }

We also could have omitted the first definition; a function definition like the one immediately above automatically defines `generate_id` as a function of type `function(a: addr, p: port): string`. Note though that if func-name was indeed already declared, then the argument list much match exactly that of the previous definition. This includes the names of the arguments; Unlike with C, you cannot change the argument names between their first (forward) definition and the full definition of the function.

You can also define functions without using any name. These are referred to as anonymous functions, and are a type of expression.

You can only do two things with functions: call them or assign them. As an example of the latter, suppose we have:

        local id_funcs: table[conn_id] of function(p: port, a: addr): string;

would declare a local variable indexed by a `conn_id` record value to yield a function of the same type as in the previous example. You could then execute:

        id_funcs[c$id] = generate_id

or call whatever function is associated with a given `conn_id`:

        print fmt("id is: %s", id_funcs[c$id](80/tcp, 1.2.3.4));

#
Event handlers

Event handlers are nearly identical in both syntax and semantics to functions, with the two differences being that event handlers have no return type since they never return a value, and you cannot call an event handler. You declare an event handler using:

> `event (` argument `)`

So, or example,

        local eh: event(attack_source: addr, severity: count)

declares the local variable `eh` to have a type corresponding to an event handler that takes two arguments, `attack_source` of type `addr`, and `severity` of type `count`.

To declare an event handler along with its body, the syntax is:

> `event` handler `(` argument `)` `{` statement `}`

As with functions, you can assign event handlers to variables of the same type. Instead of calling event handlers like functions, though, instead they are invoked. This can happen in one of three ways:

From the event engine
  When the event engine detects an event for which you have defined a corresponding event handler, it queues an event for that handler. The handler is invoked as soon as the event engine finishes processing the current packet (and invoking any other event handlers that were queued first). The various event handlers known to the event engine are discussed in Chapter § .

Via the `event` statement
  The `event` statement queues an event for the given event handler for immediate processing. For example:

          event password_exposed(c, user, password);

  queues an inovocation of the event handler `password_exposed` with the arguments `c`, `user`, and `password`. Note that `password_exposed` must have been previously declared as an event handler with a compatible set of arguments.

  Or, if we had a local variable `eh` as defined above, we could execute:

          event eh(src, how_severe);

  if `src` is of type `addr` and `how_severe` of type `count`.

Via the `schedule` expression
  The `schedule`xpression queues an event for future invocation. For example:

          schedule 5 secs { password_exposed(c, user, password) };

  would cause `password_exposed` to be invoked 5 seconds in the future.

#
The `any` type

The `any` type is a type used internally by Bro to bypass strong typing. For example, the `fmt` function takes arguments of type `any`, because its arguments can be of different types, and of variable length. However, the `any` type is not supported for use by the user; while Bro lets you declare variables of type `any`, it does not allow assignment to them. This may change in the future. Note, though, that you can achieve some of the same effect using `record` values with `&optional` fields.

#
Statements and Expressions

You express Bro's analysis of network traffic using event handlers, which, as discussed in § , are essentially subroutines written in Bro's policy scripting language. In this chapter we discuss the different types of statements and expressions available for expressing event handlers and the auxiliary functions they use.

# Statements

Bro functions and event handlers are written in an imperative style, and the statements available for doing so are similar to those provided in C. As in C, statements are terminated with a semi-colon. There are no restrictions on how many lines a statement can span. Whitespace can appear between any of the syntatic components in a statement, and its presence always serves as a separator (that is, a single syntactic component cannot in general contain embedded whitespace, unless it is escaped in some form, such as appearing inside a string literal).

Bro provides the following types of statements:

  [expression] Syntax:

  > `expr ;`

  As in C, an expression by itself can also be used as a statement. For example, assignments, calling functions, and scheduling timers are all expressions; they also are often used as statements.

  [`print`] Syntax:

  > `print [ `file` ] expr-list ;`

  The expressions are converted to a list of strings, which are then printed as a comma-separated list. If the first expression is of type `file`, then the other expressions are printed to the corresponding file; otherwise they're written to stdout.

  For control over how the strings are formatted, see `fmt` function.

  [`log`] Syntax:

  > `log expr-list ;`

  The expressions are converted to a list of strings, which are then logged as a comma-separated list. ``Logging'' means recording the values to `bro_log_file`. In addition, if Bro is reading live network traffic (as opposed to from a trace file), then the messages are also reported via syslog(3) at level `LOG_NOTICE`. If the message does not already include a timestamp, one is added.

  See the `log` module for a discussion of controlling logging behavior from your policy script. In particular, an important feature of the `log` statement is that prior to logging the giving string(s), Bro first invokes `log_hook` to determine whether to suppress the logging.

  [`event`] Syntax:

  > `event expr ( expr-list ) ;`

  Evaluates expr to obtain an event handler and queues an event for it with the value corresponding to the optional comma-separated list of values given by expr-list.

  Note: `event` statements look syntactically just like function calls, other than the keyword ```event`''. However, function calls are expressions, while queueing an event is not, since it does not return a value.

  [`if`] Syntax:

  > `if ( expr ) stmt`
  > `if ( expr ) stmt else stmt`

  Evaluates expr, which must yield a `bool` value. If true, executes stmt. For the second form, if false, executes stmt.

  [`for`] Syntax:

  > `for ( var in expr ) stmt`

  Iterates over the indices of expr, which must evaluate to either a `set` or a `table`. For each iteration, var is set to one of the indices and stmt is executed. var needn't have been previously declared (in which case its type is implicitly inferred from that of the indices of expr), and must not be a global variable.

  If expr is a `set`, then the indices correspond to the members of the set. If expr is a `table`, then they correspond to the indices of the table.

  Deficiency: You can only use `for` statements to iterate over sets and tables with a single, non-compound index type. You can't iterate over multi-dimensional or compound indices.

  Deficiency: Bro lacks ways of controlling the order in which it iterates over the indices.

  [`next`] Syntax:

  > `next ;`

  Only valid within a `for` statement. When executed, causes the loop to proceed to the next iteration value (i.e., the next index value).

  [`break`] Syntax:

  > `break ;`

  Only valid within a `for` statement. When executed, causes the loop to immediately exit.

  [`return`] Syntax:

  > `return [ `expr` ] ;`

  Immediately exits the current function or event handler. For a function, returns the value expr (which is omitted if the function does not return a value, or for event handlers).

  [`add`] Syntax:

  > `add expr [ `expr` ] ;`

  Adds the element specified by expr to the `set` given by expr. For example,

          global active_hosts: set[addr, port];
          ...
          add active_hosts[1.44.33.7, 80/tcp];

  addes an element corresponding to the pair `1.44.33.7` and `80/tcp` to the set `active_hosts`.

  [`delete`] Syntax:

  > `delete expr [ `expr` ] ;`

  Deletes the corresponding value, where expr corresponds to a set or table, and expr an element/index of the set/table. If the element is not in the set/table, does nothing.

  [compound] Compound statements are formed from a list of (zero or more) statements enclosed in `{}`'s:

  > `{ statement }`

  [null] A lone:

  > `;`

  denotes an empty, do-nothing statement.

  [`local`, `const`] Syntax:

  > `local var [ `: type` ] [ `= initialization` ] [ `attributes` ] ;`
  > `const var [ `: type` ] [ `= initialization` ] [ `attributes` ] ;`

  Declares a local variable with the given type, initialization, and attributes, all of which are optional. The syntax of these fields is the same as for global variable declarations. The second form likewise declares a local variable, but one which is constant: trying to assign a new value to it results in an error. Deficiency: Currently, this `const` restriction isn't detected/enforce.

  Unlike with C, the scope of a local variable is from the point of declaration to the end of the encompassing function or event handler.

# Expressions

Expressions in Bro are very similar to those in C, with similar precedence:

  [parenthesized] Syntax:

  > `( expr )`

  Parentheses are used as usual to override precedence.

  [constant] Any constant value (§ ) is an expression.

  [variable] The name of a variablevariables is an expression.

  [increment, decrement] Syntax:

  > `++ expr`
  > `- expr`

  Increments or decrements the given expression, which must correspond to an assignable value (variable, table element, or record element) and of a number type.

  Yields the value of the expression after the increment.

  Unlike with C, these operators only are defined for ``pre''-increment/decrement; there is no post-increment/decrement.

  [negation] Syntax:

  > `! expr`
  > `- expr`

  Yields the boolean § or arithmetic negation for values of boolean or numeric (or `interval`) types, respectively.

  [positivation] Syntax:

  > `+ expr`

  Yields the value of expr, which must be of type numeric or `interval`.

  The point of this operator is to explicitly convert a value of type `count` to `int`. For example, suppose you want to declare a local variable `code` to be of type `int`, but initialized to the value `2`. If you used:

          local code = 2;

  then Bro's implicit typing would make it of type `count`, because that's the type of a constant specified by a string of digits. You could instead use:

          local code = +2;

  to direct the type inferencing to instead assign a type of `int` to `code`. Or, of course, you could specify the type explicitly:

          local code:int = 2;

  [arithmetic] Syntax:

  > `expr + expr`
  > `expr - expr`
  > `expr * expr`
  > `expr / expr`
  > `expr % expr`

  The usual C arithmetic operators, defined for numeric types, except modulus (`%`) is only defined for integral types.

  [logical] Syntax:

  > `expr `&&` expr`
  > `expr `||` expr`

  The usual C logical operators, defined for boolean types.

  [equality] Syntax:

  > `expr `==` expr`
  > `expr `"!=` expr`

  Compares two values for equality or inequality, yielding a `bool` value. Defined for all non-compound types except `pattern`.

  [relational] Syntax:

  > `expr `<` expr`
  > `expr `<=` expr`
  > `expr `>` expr`
  > `expr `>=` expr`

  Compares two values for magnitude ordering, yielding a `bool` value. Defined for values of type numeric, `time`, `interval`, `port`, or `addr`.

  Note: TCP `port` values are considered less than UDP `port` values.

  Note: IPv4 `addr` values less than IPv6 `addr` values.

  Deficiency: Should also be defined at for `string` values.

  [conditional] Syntax:

  > `expr ? expr : expr`

  Evaluates expr and, if true, evaluates and yields expr, otherwise evaluates and yields expr. expr and expr must have compatible types.

  [assignment] Syntax:

  > `expr = expr`

  Assigns the value of expr to the storage defined by expr, which must be an assignable value (variable, table element, or record element). Yields the assigned value.

  [function call] Syntax:

  > `expr ( expr-list )`

  Evaluates expr to obtain a value of type `function`, which is then invoked with its arguments bound left-to-right to the values obtained from the comma-separated list of expressions expr-list. Each element of expr-list must be assignment-compatible with the corresponding formal argument in the type of expr. The list may (and must) be empty if the function does not take any parameters.

  [anonymous function] Syntax:

  > `function ( parameters ) body`

  Defines an anonymous function, which, in abstract terms, is how you specify a constant of type `function`. parameters has the syntax of parameter declarations for regular function definitions, as does body, which is just a list of statements enclosed in braces.

  Anonymous functions can be used anywhere you'd usually instead use a function declared in the usual direct fashion. For example, consider the function:

          function demo(msg: string): bool
              {
              if ( msg == "do the demo" )
                  {
                  print "got it";
                  return T;
                  }
              else
                  return F;
              }

  You could instead declare `demo` as a global variable of type function:

      global demo: function(msg: string): bool;

  and then later assign to it an anonymous function:

          demo = function (msg: string): bool
              {
              if ( msg == "do the demo" )
                  {
                  print "got it";
                  return T;
                  }
              else
                  return F;
              };

  You can even call the anonymous function directly:

          (function (msg: string): bool
              {
              if ( msg == "do the demo" )
                  {
                  print "got it";
                  return T;
                  }
              else
                  return F;
              })("do the demo")

  though to do so you need to enclose the function in parentheses to avoid confusing Bro's parser.

  One particularly handy form of anonymous function is that used for `&default`.

  [event scheduling] Syntax:

  > `schedule expr `{` expr ( expr-list ) `}``

  Evaluates expr to obtain a value of type `interval`, and schedules the event given by expr with parameters expr-list for that time. Note that the expressions are all evaluated and bound at the time of execution of the `schedule` expression; evaluation is not deferred until the future execution of the event handler.

  For example, we could define the following event handler:

          event once_in_a_blue_moon(moon_phase: interval)
              {
              print fmt("wow, a blue moon - phase %s", moon_phase);
              }

  and then we could schedule delivery of the event for 6 hours from the present, with a `moon_phase` of 12 days, using:

          schedule +6 hr { once_in_a_blue_moon(12 days) };

  Note: The syntax is admittedly a bit clunky. In particular, it's easy to (i) forget to include the braces (which are needed to avoid confusing Bro's parser), (ii) forget the final semi-colon if the `schedule` expression is being used as an expression-statement, or (iii) erroneously place a semi-colon after the event specification but before the closing brace.

  Timer invocation is inexact. In general, Bro uses arriving packets to serve as its clock (when reading a trace file off-line, this is still the case--the timestamp of the latest packet read from the trace is used as the notion of ``now''). Once this clock reaches or passes the time associated with a queued event, Bro will invoke the event handler, which is termed ``expiring'' the timer. (However, Bro will only invoke `max_timer_expires` timers per packet, and these include its own internal timers for managing connection state, so this can also delay invocation.)

  It will also expire all pending timers (whose time has not yet arrived) when Bro terminates; if you don't want those event handlers to activate in this instance, you need to test `done_with_network`.

  You would think that `schedule` should just be a statement like `event` invocation is, rather than an expression. But it actually does return a value, of the undocumented type `timer`. In the future, Bro may provide mechanisms for manipulating such timers; for example, to cancel them if you no longer want them to expire.

  [index] Syntax:

  > `expr [ expr-list ]`

  Returns the sub-value of expr indexed by the value of expr-list, which must be compatible with the index type of expr.

  expr-list is a comma-separated list of expressions (with at least one expression listed) whose values are matched left-to-right against the index types of expr.

  The only type of value that can be indexed in this fashion is a `table`. Note: `set`'s cannot be indexed because they do not yield any value. Use `in` to test for set membership.

  [membership] Syntax:

  > `expr in expr`
  > `expr !in expr`

  Yields true (false, respectively) if the index expr is present in the `table` or `set` expr.

  For example, if `alert_level` is a `table` index by an address and yielding a count:

          global alert_level: table[addr] of count;

  then we could test whether the address `127.0.0.1` is present using:

          127.0.0.1 in alert_level

  For `table`'s and `set`'s indexed by multiple dimensions, you enclose expr in brackets. For example, if we have:

          global connection_seen: set[addr, addr];

  then we could test for the presence of the element indexed by `8.1.14.2` and `129.186.0.77` using:

          [8.1.14.2, 129.186.0.77] in connection_seen

  We can also instead use a corresponding `record` type. If we had

          local t = [$x = 8.1.14.2, $y = 129.186.0.77]

  then we could test:

          t in connection_seen

  [pattern matching] Syntax:

  > `expr == expr`
  > `expr "!= expr`
  > `expr in expr`
  > `expr "!in expr`

  As discussed for pattern values, the first two forms yield true (false) if the `pattern` expr exactly matches the `string` expr. (You can also list the `string` value on the left-hand side of the operator and the `pattern` on the right.)

  The second two forms yield true (false) if the `pattern` expr is present within the `string` expr. (For these, you must list the pattern as the left-hand operand.)

  [record field access] Syntax:

  > `expr $ field-name`

  Returns the given field field-name of the record expr. If the record does not contain the given field, a compile-time error results.

  [record constructor] Syntax:

  > `[ field-constructor-list ]`

  Constructs a `record` value. The field-constructor-list is a comma-separated list of individual field constructors, which have the syntax:

  > `$ field-name = expr`

  For example,

          [$foo = 3, $bar = 23/tcp]

  yields a `record` with two fields, `foo` of type `count` and `bar` of type `port`. The values used in the constructor needn't be constants, however; they can be any expression of an assignable type.

  [record field test] Syntax:

  > `expr `?$` field-name`

  Returns true if the given field has been set in the record yielded by expr. Note that field-name must correspond to one of the fields in the record type of expr (otherwise, the expression would always be false). The point of this operator is to test whether an `&optional` field of a record has been assigned to.

  For example, suppose we have:

          type rap_sheet: record {
              num_scans: count &optional;
              first_activity: time;
          };
          global the_goods: table[addr] of rap_sheet;

  and we want to test whether the address held in the variable `perp` exists in `the_goods` and, if so, whether `num_scans` has been assigned to, then we could use:

          perp in the_goods && the_goods[perp]?$num_scans

#
Global and Local Variables

# Overview

Bro variables can be complicated to understand because they have a number of possibilities and features. They can be global or local in scope; modifiable or constant (unchangeable); explicitly or implicitly typed; optionally initialized; defined to have additional attributes; and, for global variables, redefined to have a different initialization or different attributes from their first declaration.

Rather than giving the full syntax for variable declarations, which is messy, in the following sections we discuss each of these facets of variables in turn, illustrating them with the minimal necessary syntax. However, keep in mind that the features can be combined as needed in a variable declaration.

##
Scope

`global` `local` Global variables are available throughout your policy script (once declared), while the scope of local variables is confined to the function or event handler in which they're declared. You indicate the variable's type using a corresponding keyword:

> `global` name `:` type `;`

or

> `local` name `:` type `;`

which declares name to have the given type and the corresponding scope.

You can intermix function/event handler definitions with declarations of global variables, and, indeed, they're in fact the same thing (that is, a function or event handler definition is equivalent to defining a global variable of type `function` or `event` and associating its initial value with that of the function or event handler). So the following is fine:

        global a: count;

        function b(p: port): string
            {
            if ( p < 1024/tcp )
                return "privileged";
            else
                return "ephemeral";
            }

        global c: addr;

However, you cannot mix declarations of global variables with global statements; the following is not allowed:

        print "hello, world";
        global a: count;

Local variables, on the other hand, can only be declared within a function or event handler. (Unlike for global statements, these declarations can come after statements.) Their scope persists to the end of the function. For example:

        function b(p: port): string
            {
            if ( p < 1024/tcp )
                local port_type = "privileged";
            else
                port_type = "ephemeral";

            return port_type;
            }

##
Modifiability

`const` For both global and local variables, you can declare that the variable cannot be modified by declaring it using the `const` keyword rather than `global` or `local`:

        const response_script = "./scripts/nuke-em";

Note that `const` variables must be initialized (otherwise, of course, there's no way for them to ever hold a useful value).

The utility of marking a variable as unmodifiable is for clarity in expressing your script--making it explicit that a particular value will never change--and also allows Bro to possibly optimize accesses to the variable (though it does little of this currently).

Note that `const` variables can be redefined via `redef`.

##
Typing

When you define a variable, you can explicitly type it by specifying its type after a colon. For example,

        global a: count;

directly indicates that `a`'s type is `count`.

However, Bro can also implicitly type the variable by looking at the type of the expression you use to initialize the variable:

        global a = 5;

also declares `a`'s type to be `count`, since that's the type of the initialization expression (the constant `5`). There is no difference between this declaration and:

        global a: count = 5;

except that it is more concise both to write and to read. In particular, Bro remains strongly typed, even though it also supports implicit typing; the key is that once the type is implicitly inferred, it is thereafter strongly enforced.

Bro's type inference is fairly powerful: it can generally figure out the type whatever initialization expression you use. For example, it correctly infers that:

        global c = { [21/tcp, "ftp"], [[80/tcp, 8000/tcp, 8080/tcp], "http"], };

specifies that `c`'s type is `set[port, string]`. But for still more complicated expressions, it is not always able to infer the correct type. When this occurs, you need to explicitly specify the type.

##
Initialization

When defining a variable, you can optionally specify an initial value for the variable:

        global a = 5;

indicates that the initial value of `a` is the value `5` (and also implicitly types `a` as type `count`, per § ).

The syntax of an initialization is ```=` expression'', where the given expression must be assignment-compatible with the variable's type (if explicitly given). Tables and sets also have special initializer forms, which are discussed in § and § .

##
Attributes

When defining a variable, you can optionally specify a set of attributes associated with the variable, which specify additional properties associated with it. Attributes have two forms:

> `&` attr

for attributes that are specified simply using their name, and

> `&` attr `=` expr

for attributes that have a value associated with them.

The attributes `&redef` `&add_func` and `&delete_func`, pertain to redefining variables; they are discussed in § .

The attributes `&default`, `&create_expire`, `&read_expire`, `&write_expire`, and `&expire_func` are for use with `table`'s and `set`'s. See § for discussion.

The attribute `&optional` specifies that a `record` field is optional. See § for discussion.

Finall, to specify multiple attributes, you do not separate them with commas (doing so would actually make Bro's grammar ambiguous), but just list them one after another. For example:

        global a: table[port] of string &redef &default="missing";

##
Refinement

To do.

`&redef`

`&add_func`

`&delete_func`

#
Predefined Variables and Functions

Fix me: The variables and functions are presented alphabetically. They should instead be organized into those with related purposes, because they can already be located alphabetically using the index.

#
Predefined Variables

Bro predefines and responds to the following variables:

  [``bro_log_file : file``] Used to record the messages logged by `log` statements.

  Default: stderr, unless you `@load` the `log` analyzer; see § for further discussion.

  [``capture_filter : string``] Specifies what packets Bro's filter should record (§ ).

  [``direct_login_prompts : set[string]``] Strings that when seen in a login dialog indicate that the user will be directly logged in after entering their username, without requiring a password (§ ).

  [``discarder_maxlen : int``] The maximum amount of data that Bro should pass to a TCP or UDP discarder (§ ).

  Default: 128 bytes.

  [``done_with_network : bool``] Set to true when Bro is done reading from the network (or from the save files being played back, per § ). The variable is set by a handler for `net_done`.

  Default: initially set to false.

  [``interfaces : string``] A blank-separated list of network interfaces from which Bro should read network traffic. Bro merges packets from the interfaces according to their timestamps. Deficiency: All interfaces must have the same link layer type.

  If empty, then Bro does not read any network traffic, unless one or more interfaces are specified using the `-i` flag.

  Note: `interfaces` has an `&add_func` that allows you to add interfaces to the list simply using a `+=` initialization (§ ).

  Default: empty.

  [``login_failure_msgs : set[string]``] Strings that when seen in a `login` dialog indicate that a user's attempt to authenticate failed (§ ).

  [``login_non_failure_msgs : set[string]``] Exceptions to `login_failure_msgs` (§ ).

  [``login_prompts : set[string]``] Strings that when seen in a `login` dialog indicate a prompt for a username (§ ).

  [``login_success_msgs : set[string]``] Strings that when seen in a `login` dialog indicate that the user successfully authenticated (§ ).

  [``login_timeouts : set[string]``] Strings that when seen in a `login` dialog indicate that the login server timed out the user's attempt to authenticate (§ ).

  [``max_timer_expires : count``] Sets an upper limit on how many pending timers Bro will expire per newly arriving packet. If set to 0, then Bro expires all pending timers whose time has come or past. This variable trades off timer accuracy and memory requirements (because a number of Bro's internal timers relate to expiring state) with potentially bursty load spikes due to a lot of timers expiring at the same time, which can trigger the watchdog, if active.

  [``restrict_filter : string``] Restricts what packets Bro's filter should record (§ ).

  [``skip_authentication : set[string]``] Strings that when seen in a `login` dialog indicate that the analyzer should skip attempting to follow the authentication dialog (§ ).

# Predefined Functions

Bro provides a number of built-in functions:

  [``active_connection (id: conn_id): bool``] Returns true if the given connection identifier (originator/responder addresses and ports) corresponds to a currently-active connection.

  [``active_file (f: file): bool``] Returns true if the given `file` is open.

  [``add_interface (iold: string, inew: string): string``] Used to refine the initialization of `interfaces`. Meant for internal use, and as an example of refinement (§ ).

  [``add_tcpdump_filter (fold: string, fnew: string): string``] Used to refine the initializations of `capture_filter` and `restrict_filter`. Meant for internal use, and as an example of refinement (§ ).

``log_hook (msg: string): bool``
  If you define this function, then Bro will call it with each string it is about to log. The function should return true if Bro should go ahead and log the message, false otherwise. See § for further discussion and an example.

  [``byte_len (s: string): count``] Returns the number of bytes in the given string. This includes any embedded NULs, and also a trailing NUL, if any (which is why the function isn't called strlen; to remind the user that Bro strings can include NULs).

  [``cat (args: any): string``] Returns the concatenation of the string representation of its arguments, which can be of any type. For example, `cat("foo", 3, T)` returns `"foo3T"`.

  [``clean (s: string): string``] Returns a cleaned up version of `s`, meaning that:

  - embedded NULs become the text ```\0`''
  - embedded DELs (delete characters) become the text ```^?`''
  - ASCII ``control'' characters with code become the text ```^`Letter'', where Letter is the corresponding (upper case) control character; for example, ASCII 2 becomes ```^B`''
  - ASCII ``control'' characters with codes between 26 and 32 (non-inclusive) become the text ```\x` hex-code''; for example, ASCII 31 becomes ```\x1f`''
  - if the string does not yet have a trailing NUL, one is added.

  [``close (f: file): bool``] Flushes any buffered output for the given file and closes it. Returns true if the file was open, false if already closed or never opened.

  [``connection_record (id: conn_id): connection``] Returns the `connection` record corresponding to the given connection identifier. Note: If the connection does not exist, then exits with a fatal run-time error.

  Deficiency: If Bro had an exception mechanism, then we could avoid the fatal run-time error, and likewise could get rid of `active_connection`.

  [``contains_string (big: string, little: string): bool``] Returns true if the string `little` occurs somewhere within `big`, false otherwise.

  [``current_time (): time``] Returns the current clock time. You will usually instead want to use `network_time`.

  [``discarder_check_icmp (i: ip_hdr, ih: icmp_hdr): bool``] Not documented. [``discarder_check_ip (i: ip_hdr): bool``] Not documented. [``discarder_check_tcp (i: ip_hdr, t: tcp_hdr, d: string): bool``] Not documented. [``discarder_check_udp (i: ip_hdr, u: udp_hdr, d: string): bool``] Not documented.

  [``edit (s: string, edit_char: string): string``] Returns a version of `s` assuming that `edit_char` is the ``backspace'' character (usually `"\x08"` for backspace or `"\x7f"` for DEL). For example, `edit("hello there", "e")` returns `"llo t"`.

  `edit_char` must be a string of exactly one character, or Bro generates a run-time error and uses the first character in the string.

  Deficiency: To do a proper job, `edit` should also know about delete-word and delete-line editing; and it would be very convenient if it could do multiple types of edits all in one shot, rather than requiring separate invocations.

  [``exit (): int``] Exits Bro with a status of 0.

  Deficiency: This function should probably allow you to specify the exit status.

  Note: If you invoke this function, then the usual cleanup functions `net_done` and `bro_done` are not invoked. There probably should be an additional ```shutdown`'' function that provides for cleaner termination.

  [``flush_all (): bool``] Flushes all open files to disk.

  [``fmt (args: any): string``] Performs sprintf-style formatting. The first argument gives the format specifier to which the remaining arguments are formatted, left-to-right. As with sprintf, the format for each argument is introduced using ```%`'', and formats beginning with a positive integer specify that the given field should have a width of characters. Fields with fewer characters are right-padded with blanks up to this width.

  A format specifier of ```.`'' (coming after , if present) instructs `fmt` to use a precision of digits. You can only specify a precision for the `e`, `f` or `g` formats. (`fmt` generates a run-time error if either or exceeds 127.)

  The different format specifiers are:

  `%`
    A literal percent-sign character.

  D
    Format as a date. Valid only for values of type `time`.

    The exact format is yy-mm-dd-hh:mm:ss for the local time zone, per strftime.

  d
    Format as an integer. Valid for types `bool`, `count`, `int`, `port`, `addr`, and `net`, with the latter three being converted from network order to host order prior to formatting. `bool` values of true format as the number 1, and false as 0.

  e, f, g
    Format as a floating point value. Valid for types `double`, `time`, and `interval`. The formatting is the same as for printf, including the field width and precision .

  Given no arguments, `fmt` returns an empty string.

  Given a non-string first argument, `fmt` returns the concatenation of all its arguments, per `cat`.

  Finally, given the wrong number of additional arguments for the given format specifier, `fmt` generates a run-time error.

  [``get_login_state (c: conn_id): count``] Returns the state of the given login (Telnet or Rlogin) connection, one of:

  `LOGIN_STATE_AUTHENTICATE`
    The connection is in its initial authentication dialog.

  `LOGIN_STATE_LOGGED_IN`
    The analyzer believes the user has successfully authenticated.

  `LOGIN_STATE_SKIP`
    The analyzer has skipped any further processing of the connection.

  `LOGIN_STATE_CONFUSED`
    The analyzer has concluded that it does not correctly know the state of the connection, and/or the username associated with it (§ ).

  or a run-time error and a value of `LOGIN_STATE_AUTHENTICATE` if the connection is not a login connection.

  [``get_orig_seq (c: conn_id): count``] Returns the highest sequence number sent by a connection's originator, or 0 if there's no such TCP connection. Sequence numbers are absolute (i.e., they reflect the values seen directly in packet headers; they are not relative to the beginning of the connection).

  [``get_resp_seq (c: conn_id): count``] Returns the highest sequence number sent by a connection's responder, or 0 if there's no such TCP connection.

  [``getenv (var: string): string``] Looks up the given environment variable and returns its value, or an empty string if it is not defined.

  [``is_tcp_port (p: port): bool``] Returns true if the given `port` value corresponds to a TCP port, false otherwise (i.e., it belongs to a UDP port).

  [``length (args: any): count``] Returns the number of elements in its argument, which must be of type `table` or `set`. If not exactly one argument is specified, or if the argument is not a table or a set, then generates a run-time message and returns 0.

  Deficiency: If Bro had a union type, then we could get rid of the magic ```args: any`'' specification and catch parameter mismatches at compile-time instead of run-time.

  [``log_file_name (tag: string): string``] Returns a name for a log file (such as `weird` or `red`) in a standard form. The form depends on whether `$BRO_ID` is set. If so, then the format is ```<`tag`>.<$BRO_ID>`''. Otherwise, it is simply `tag`.

  [``mask_addr (a: addr, top_bits_to_keep: count): addr``] Returns the address `a` masked down to the number of upper bits indicated by `top_bits_to_keep`, which must be greater than 0 and less than 33. For example, `mask_addr(1.2.3.4, 18)` returns `1.2.0.0`, and `mask_addr(1.2.255.4, 18)` returns `1.2.192.0`.

  Compare with `to_net`.

  [``max_count (a: count, b: count): count``] Returns the larger of `a` or `b`.

  [``max_double (a: double, b: double): double``] Returns the larger of `a` or `b`.

  [``max_interval (a: interval, b: interval): interval``] Returns the larger of `a` or `b`.

  Deficiency: If Bro supported polymorphic functions, then this function could be merged with its predecessors, gaining simplicity and clarity.

  [``min_count (a: count, b: count): count``] Returns the smaller of `a` or `b`.

  [``min_double (a: double, b: double): double``] Returns the smaller of `a` or `b`.

  [``min_interval (a: interval, b: interval): interval``] Returns the smaller of `a` or `b`.

  Deficiency: If Bro supported polymorphic functions, then this function could be merged with its predecessors, gaining simplicity and clarity.

  [``mkdir (f: string): bool``] Creates a directory with the given name, if it does not already exist. Returns true upon success, false (with a run-time message) if unsuccessful.

  [``network_time (): time``] Returns the timestamp of the most recently read packet, whether read from a live network interface or from a save file (§ ). Compare against `current_time`. In general, you should use `network_time` unless you're using Bro for non-networking uses (such as general scripting; not particularly recommended), because otherwise your script may behave very differently on live traffic versus played-back traffic from a save file.

  [``open (f: string): file``] Opens the given filename for write access. Creates the file if it does not already exist. Generates a run-time error if the file cannot be opened/created.

  [``open_for_append (f: string): file``] Opens the given filename for append access. Creates the file if it does not already exist. Generates a run-time error if the file cannot be opened/created.

  [``open_log_file (tag: string): file``] Opens a log file associated with the given tag, using a filename format as returned by `log_file_name`.

  [``parse_ftp_pasv (s: string): ftp_port``] Parses the server's reply to an FTP `PASV` command to extract the IP address and port number indicated by the server. The values are returned in an `ftp_port` record, which has three fields: `h`, the address ( is mnemonic for host); `p`, the (TCP) port; and `valid`, a boolean that is true if the server's reply was in the required format, false if not, or if any of the individual values (or the indicated port number) are out of range.

  [``parse_ftp_port (s: string): ftp_port``] Parses the argument included in a client's FTP `PORT` request to extract the IP address and port number indicated by the server. The values are returned in an `ftp_port` record, which has three fields, as indicated in the discussion of `parse_ftp_pasv`.

  [``reading_live_traffic (): bool``] Returns true if Bro was invoked to read live network traffic (from one or more network interfaces, per § ), false if it's reading from save files being played back (§ ).

  Note: This function returns true even after Bro has stopped reading network traffic, for example due to receiving a termination signal (§ ).

  Table 6.1: Different types of directions for `set_contents_file`.
  Direction | Meaning
  `CONTENTS_NONE` | Stop recording the connection's contents.
  `CONTENTS_ORIG` | Record the data sent by the connection originator (often the client).
  `CONTENTS_RESP` | Record the data sent by the connection responder (often the server).
  `CONTENTS_BOTH` | Record the data sent in both directions.

  [``set_buf (f: file, buffered: bool)``] Specifies that writing to the given file should either be fully buffered (if `buffered` is true), or line-buffered (if false). Does not return a value.

  [``set_contents_file (c: conn_id, direction: count, f: file): bool``] Specifies that the traffic stream of the given connection in the given direction should be recorded to the given file. `direction` is one of the values given in Table 6.2.

  Note: `CONTENTS_BOTH` results in the two directions being intermixed in the file, in the order the data was seen by Bro.

  Note: The data recorded to the file reflects the byte stream, not the contents of individual packets. Reordering and duplicates are removed. If any data is missing, the recording stops at the missing data; see `ack_above_hole` for how this can happen.

  Deficiency: Bro begins recording the traffic stream starting with new traffic it sees. Experience has shown it would be highly handy if Bro could record the entire connection to the file, including previously seen traffic. In principle, this is possible if Bro is recording the traffic to a save file (§ ), which a separate utility program could then read to extract the stream.

  Returns true upon success, false upon an error.

  [``set_login_state (c: conn_id, new_state: count): bool``] Manually sets the state of the given login (Telnet or Rlogin) connection to `new_state`, which should be one of the values described in `get_login_state`.

  Generates a run-time error and returns false if the connection is not a login connection. Otherwise, returns true.

  [``set_record_packets (c: conn_id, do_record: bool): bool``] Controls whether Bro should or should not record the packets corresponding to the given connection to the save file (§ ), if any.

  Returns true upon success, false upon an error.

  [``skip_further_processing (c: conn_id): bool``] Informs bro that it should skip any further processing of the contents of the given connection. In particular, Bro will refrain from reassembling the TCP byte stream and from generating events relating to any analyzers that have been processing the connection. Bro will still generate connection-oriented events such as `connection_finished`.

  This function provides a way to shed some load in order to reduce the computational burden placed on the monitor.

  Returns true upon success, false upon an error.

  [``sub_bytes (s: string, start: count, n: count): string``] Returns a copy of `n` bytes from the given string, starting at position `start`. The beginning of a string corresponds to position 1.

  If `start` is 0 or exceeds the length of the string, returns an empty string.

  If the string does not have `n` characters from `start` to its end, then returns the characters from `start` to the end.

  [``system (s: string): int``] Runs the given string as a sh command (via C's system call).

  Note: The command is run in the background with stdout redirected to stderr.

  Returns the return value from the system call. Note: This corresponds to the status of backgrounding the given command, not to the exit status of the command itself. A value of 127 corresponds to a failure to execute sh, and -1 to an internal system failure.

  [``to_lower (s: string): string``] Returns a copy of the given string with the uppercase letters (as indicated by isascii and isupper) folded to lowercase (via tolower).

  [``to_net (a: addr): net``] Returns the network prefix historically associated with the given address. That is, if `a`'s leading octet is less than 128, then returns `<`a`>`/8; if between 128 and 191, inclusive, then `<`a`>`/16; if between 192 and 223, then `<`a`>`/24; and, otherwise, `<`a`>`/32. See the discussion of the `net` type for more about network prefixes.

  Generates a run-time error and returns `0.0.0.0` if the address is IPv6.

  Note: Such network prefixes have become obsolete with the advent of CIDR; still, for some sites they prove useful because they correspond to existing address allocations.

  Compare with `mask_addr`.

  [``to_upper (s: string): string``] Returns a copy of the given string with the lowercase letters (as indicated by isascii and islower) folded to uppercase (via toupper).

##
Run-time errors for non-existing connections

Note that for all functions that take a `conn_id` argument except `active_connection`, Bro generates a run-time error and returns false if the given connection does not exist.

## Run-time errors for strings with NULs

While Bro allows NULs embedded within strings (§ ), for many of the predefined functions, their presence spells trouble, particularly when the string is being passed to a C run-time function. The same holds for strings that are not NUL-terminated. Because Bro string constants and values returned by Bro functions that construct strings such as `fmt` and `cat` are all NUL-terminated, such strings will not ordinarily arise; but their presence could indicate an attacker attempting to manipulate either a TCP endpoint, or the monitor itself, into misinterpreting a string they're sending.

In general, any of the functions above that are passed a string argument will check for the presence of an embedded NUL or the lack of a terminating NUL. If either occurs, they generate a run-time message, and the string is transformed into the value `"<string-with-NUL>"`.

There are three exceptions: `clean`, `byte_len`, and `sub_bytes`. These functions do not complain about embedded NULs or lack of trailing NULs.

##
Functions for manipulating strings

Fix me: Missing

##
Functions for manipulating time

Fix me: Missing

#
Analyzers and Events

In this chapter we detail the different analyzers that Bro provides. Some analyzers look at traffic in fairly generic terms, such as at the level of TCP or UDP connections. Others delve into the specifics of a particular application that is carried on top of TCP or UDP.

As we use the term here, analyzer primarily refers to Bro's event engine. We use the term script to refer to a set of event handlers (and related functions and variables) written in the Bro language; module to refer to a script that serves primarily to provide utility (helper) functions and variables, rather than event handlers; and handler to denote an event handler written in the Bro language. Furthermore, the standard script is the script that comes with the Bro distribution for handling the events generated by a particular analyzer.

Note: However, we also sometimes use analyzer to refer to the event handler that processes events generated by the event engine.

We characterize the analyzers in terms of what events they generate, but don't here go into the details of how they generate the events (i.e., the nitty gritty C++ implementations of the analyzers).

#
Activating an Analyzer

In general, Bro will only do the work associated with a particular analyzer if your policy script defines one or more event handlers associated with the analyzer. For example, Bro will instantiate an FTP analyzer only if your script defines an `ftp_request` or `ftp_reply` handler. If it doesn't, then when a new FTP connection begins, Bro will only instantiate a generic TCP analyzer for it. This is an important point, because some analyzers can require Bro to capture a large volume of traffic (§ ) and perform a lot of computation; therefore, you need to have a way to trade off between the type of analysis you do and the performance requirements it entails, so you can strike the best balance for your particular monitoring needs.

Deficiency: While Bro attempts to instantiate an analyzer if you define a handler for any of the events the analyzer generates, its method for doing so is incomplete: if you only define an analyzer's less mainstream handlers, Bro may fail to instantiate the analyzer.

##
Loading Analyzers

The simplest way to use an analyzer is to `@load` the standard script associated with the analyzer. (See § for a discussion of `@load`.) However, there's nothing magic about these scripts; you can freely modify or write your own. The only caveat is that some scripts `@load` other scripts, so the original version may wind up being loaded even though you've also written your own version. Deficiency: It would be useful to have a mechanism to fully override one script with another.

In this chapter we discuss each of the standard scripts as we discuss their associated analyzers.

##
Filtering

Most analyzers require Bro to capture a particular type of network traffic. These traffic flows can vary immensely in volume, so different analyzers can cost greatly differing amounts in terms of performance.

Bro predefines two redefinable `string` variables that have special interpretations with regard to filtering. (See § for a discussion of redefinable variables.) `capture_filter` is a `tcpdump` filter that tells Bro what traffic it should capture. `restrict_filter` limits what traffic Bro captures. The `tcpdump` filter Bro uses is:

> `(capture_filter) and (restrict_filter)`

So, for example, if you specify:

        redef capture_filter = "port http";
        redef restrict_filter = "net 128.3";

then the corresponding `tcpdump` filter will be:

        (port http) and (net 128.3)

which will capture all TCP port 80 traffic that has either a source or destination address belonging to the `128.3` network (i.e., `128.3/16`).

If you do not define `capture_filter`, then its value is set to ```tcp or udp`''; if you do not define `restrict_filter`, then no restriction is in effect.

You may have noticed that other than their default values, the definitions of `capture_filter` and `restrict_filter` are symmetric. They differ only in the convention of how they are used. Usually, you either don't define a value for `restrict_filter` at all, or define it just once, using it to specify a restriction that holds across your environment. For example, either to confine packet capture to a subset of the traffic (like the `"net 128.3"` example above), or to exclude a particular traffic source (`"not host syn-flood.magnet.com"`) or both of these (`"net 128.3 and not host syn-flood.magnet.com"`).

For `capture_filter`, on the other hand, you usually don't define a single value, but instead refine it one or more times using the `+=` initializer. (See § for a discussion of refining a variable's initial value.) The way `capture_filter`'s refinement is defined, it constructs a filter that is the ``or'' of each of its refinements. So, for example, if at one point in your script you have:

        redef capture_filter += "port ftp";

and at another:

        redef capture_filter += "udp port 53";

and at a third:

        redef capture_filter += "len >= 512 and len <= 1024";

then the resulting `capture_filter` will be:

        (port ftp) or (udp port 53) or (len >= 512 and len <= 1024)

(except there will be more parentheses, which don't actually affect the interpretation of the filter; see § for the details of how the refinement is done, and why it leads to the extra parentheses).

`restrict_filter` has the same refinement mechanism, the ``or''ing together of the different refinement additions, though, as mentioned above, it is not usually refined.

Figure 7.1: `print-filter` prints out the `tcpdump` filter your Bro script would use and then exits.

As you add analyzers, the final `tcpdump` filter can become quite complicated. You can use the predefined `print-filter` script shown in Figure 7.1.2 to print out the filter. This script handles the `bro_init` event and exits after printing the filter. Its intended use is that you can add it to the Bro command line (```bro my-own-script print-filter`'') when you want to see what filter the script my-own-script winds up using.

There are two particular uses for `print-filter`. The first is to debug filtering problems. Unfortunately, Bro sometimes uses sufficiently complicated expressions that they tickle bugs in `tcpdump`'s optimizer. You can take the filter printed out for your script and try running it through `tcpdump` by hand, and then also try using `tcpdump`'s `-O` option to see if turning off the optimizer fixes the problem.

The second use is to provide a shadow backup to Bro: that is, a version of `tcpdump` running either on the same machine or a separate machine that uses the same network filter as Bro. While `tcpdump` can't perform any analysis of the traffic, the shadow guards against the possibility of Bro crashing, because if it does, you will still have a record of the subsequent network traffic which you can run through Bro for post-analysis.

#
General Processing Events

Bro provides the following events relating to its overall processing:

  [``bro_init ()``] generated when Bro first starts up. In particular, after Bro has initialized the network (or initialized to read from a save file) and executed any initializations and global statements (§ ), and just before Bro begins to read packets from the network input source(s).

  [``net_done (t: time)``] generated when Bro has finished reading from the network, due to either having exhausted reading the save file(s), or having received a terminating signal (§ ). Deficiency: This event is generated on a terminating signal even if Bro is not reading network traffic. `t` gives the time at which network processing finished.

  This event is generated before `bro_done`. Note: If Bro terminates due to an invocation of `exit`, then this event is not generated.

  [``bro_done ()``] generated when Bro is about to terminate, either due to having exhausted reading the save file(s), receiving a terminating signal (§ ), or because Bro was run without the network input source and has finished executing any global statements (§ ).

  This event is generated after `net_done`. If you have cleanup that only needs to be done when processing network traffic, it likely is better done using `net_done`. Note: If Bro terminates due to an invocation of `exit`, then this event is not generated.

  [``bro_signal (signal: count)``] generated when Bro receives a signal. Currently, the signals Bro handles are SIGTERM, SIGINT, and SIGHUP.

  Receiving either of the first two terminates Bro, though if Bro is in the middle of processing a set of events, it first finishes with them before shutting down. The shutdown leads to invocations of `net_done` and `bro_done`, in that order. Deficiency: In this case, Bro fails to invoke `bro_signal`, clearly a bug.

  Upon receiving SIGHUP, Bro invokes `flush_all` (in addition to your handler, if any).

  [``net_stats_update (t: time, ns: net_stats)``] This event includes two arguments, `t`, the `time` at which the event was generated, and `ns`, a `net_stats` record, as defined in Figure 7.2. Regarding this second parameter, the `pkts_recvd` field gives the total number of packets accepted by the packet filter so far during this execution of Bro; `pkts_dropped` gives the total number of packets reported dropped by the kernel; and `interface_drops` gives the total number of packets reported by the kernel as having been dropped by the network interface.

  Note: An important consideration is that, as shown by experience, the kernel's reporting of these statistics is not always accurate. In particular, the `$pkts_dropped` statistic is sometimes missing actual packet drops, and some operating systems do not support the `interface_drops` statistic at all. See the `ack_above_hole` event for an alternate way to detect if packets are being dropped.

Figure 7.2: Definition of the `net_stats` record.

#
Generic Connection Analysis

The `conn` analyzer performs generic connection analysis: connection start time, duration, sizes, hosts, and the like. You don't in general load `conn` directly, but instead do so implicitly by loading the `tcp`, `udp`, or `icmp` analyzers. Consequently, `conn` doesn't load a `capture_filter` value by itself, but instead uses whatever is set up by these more specific analyzers.

`conn` analyzes a number of events related to connections beginning or ending. We first describe the `connection` record data type that keeps track of the state associated with each connection (§ ), and then we detail the events in § . The main output of its analysis are one-line connection summaries, which we describe in § , and in § we give an overview of the different callable functions provided by `conn`.

`conn` also loads three other Bro modules: the `hot` and `scan` analyzers, and the `port-name` utility module.

##
The `connection` record

Figure 7.3: Definition of `conn_id` and `connection` records.

A `connection` record holds the state associated with a connection, as shown in Figure 7.3.1. Its first field, `id`, is defined in terms of the `conn_id` record, which has the following fields:

  [`orig_h`] The IP address of the host that originated (initiated) the connection. In ``client/server'' terminology, this is the ``client.''

  [`orig_p`] The TCP or UDP port used by the connection originator (client). For ICMP ``connections'', it is set to 0 (§ ).

  [`resp_h`] The IP address of the host that responded (received) the connection. In ``client/server'' terminology, this is the ``server.''

  [`resp_p`] The TCP or UDP port used by the connection responder (server). For ICMP ``connections'', it is set to 0 (§ ).

The `orig` and `resp` fields of a `connection` record both hold `endpoint` record values, which consist of the following fields:

  [`size`] How many bytes the given endpoint has transmitted so far. Note that for some types of filtering, the size will be zero until the connection terminates, because the nature of the filtering is to discard the connection's intermediary packets and only capture its start/stop packets (§ ).

  Table 7.1: TCP and UDP connection states, as stored in an `endpoint` record.
  State | Meaning
  `TCP_INACTIVE` | The endpoint has not sent any traffic.
  `TCP_SYN_SENT` | It has sent a SYN to initiated a connection.
  `TCP_SYN_ACK_SENT` | It has sent a SYN ACK to respond to a connection request.
  `TCP_PARTIAL` | The endpoint has been active, but we did not see the beginning of the connection.
  `TCP_ESTABLISHED` | The two endpoints have established a connection.
  `TCP_CLOSED` | The endpoint has sent a FIN in order to close its end of the connection.
  `TCP_RESET` | The endpoint has sent a RST to abruptly terminate the connection.
  `UDP_INACTIVE` | The endpoint has not sent any traffic.
  `UDP_ACTIVE` | The endpoint has sent some traffic.

  [`state`] The current state the endpoint is in with respect to the connection. Table 7.3.1 defines the different possible states for TCP and UDP connections. Deficiency: The states are currently defined as `count`, but should instead be an enumerated type; but Bro does not yet support enumerated types.

  Note: UDP ``connections'' do not have a well-defined structure, so the states for them are quite simplistic. See § for further discussion.

The remaining fields in a `connection` record are:

  [`start_time`] The time at which the first packet associated with this connection was seen.

  [`duration`] How long the connection lasted, or, if it is still active, how long since it began.

  [`service`] The name of the service associated with the connection. For example, if `$id$resp_p` is `tcp/80`, then the service will be `"http"`. Usually, this mapping is provided by the `port_names` global variable, perhaps via the `endpoint_id` function; but the service does not always directly correspond to `$id$resp_p`, which is why it's a separate field. In particular, an FTP data connection can have a `service` of `"ftp-data"` even though its `$id$resp_p` is something other than `tcp/20` (which is not consistently used by FTP servers).

  If the name of the service has not yet been determined, then this field is set to an empty string.

  [`addl`] Additional information associated with the connection. For example, for a login connection, this is the username associated with the login.

  Deficiency: A significant deficiency associated with the `addl` field is that it is simply a `string` without any further structure. In practice, this has proven too restrictive. For example, we may well want to associate an unambiguous username with a login session, and also keep track of the names associated with failed login attempts. (See the `login` analyzer for an example of how this is implemented presently.) What's needed is a notion of `union` types which can then take on a variety of values in a type-safe manner.

  If no additional information is yet associated with this connection, then this field is set to an empty string.

  [`hot`] How many times this connection has been marked as potentially sensitive or reflecting a break-in. The default value of 0 means that so far the connection has not been regarded as ``hot''.

  Note: Bro does not presently make fine-grained use of this field; the standard scripts log connections with a non-zero `hot` field, and do not in general log those that do not, though there are exceptions. In particular, the `hot` field is not rigorously maintained as an indicator of trouble; it instead is used loosely as an indicator of particular types of trouble (access to sensitive hosts or usernames).

##
Definitions of connections

Connections for TCP are well-defined, because establishing and terminating a connection plays a central part of the TCP protocol. For UDP and ICMP, however, the notion is much looser.

For UDP, a connection begins when host sends a packet to host for the first time, never having sent anything to . This transmission is termed a request, even if in fact the application protocol being used is not based on requests and replies. If sends a packet back, then that packet is termed a reply. Each packet or sends is another request or reply. Deficiency: There is presently no mechanism by which generic (non-RPC) UDP connections are terminated; Bro holds the state indefinitely. There should probably be a generic timeout for UDP connections that don't correspond to some higher-level protocol (such as RPC), and a user-accessible function to mark connections with particular timeouts.

For ICMP, Bro likewise creates a connection the first time it sees an ICMP packet from to , even if previously sent a packet to , because that earlier packet would have been for a different transport connection than the ICMP itself--the ICMP will likely refer to that connection, but it itself is not part of the connection. For simplicity, this holds even for ICMP ECHOs and ECHO_REPLYs; if you want to pair them up, you need to do so explicitly in the policy script. Deficiency: As with UDP, Bro does not time out ICMP connections.

##
Generic TCP connection events

There are a number of generic events associated with TCP connections, all of which have a single `connection` record as their argument:

  [`new_connection`] Generated whenever state for a new (TCP) connection is instantiated.

  Note: Handling this event is potentially expensive. For example, during a SYN flooding attack, every spoofed SYN packet will lead to a new `new_connection` event.

  [`connection_established`] Generated when a connection has become established, i.e., both participating endpoints have agreed to open the connection.

  [`connection_attempt`] Generated when the originator (client) has unsuccessfully attempted to establish a connection. ``Unsuccessful'' is defined as at least `ATTEMPT_INTERVAL` seconds having elapsed since the client first sent a connection establishment packet to the responder (server), where `ATTEMPT_INTERVAL` is an internal Bro variable which is presently set to 300 seconds. Deficiency: This variable should be user-settable. If you want to immediately detect that a client is attempting to connect to a server, regardless of whether it may soon succeed, then you want to handle the `new_connection` event instead.

  Note: Handling this event is potentially expensive. For example, during a SYN flooding attack, every spoofed SYN packet will lead to a new `connection_attempt` event, albeit delayed by `ATTEMPT_INTERVAL.`

  [`partial_connection`] Generated when both connection endpoints enter the `TCP_PARTIAL` state (Table 7.3.1). This means that we have seen traffic generated by each endpoint, but the activity did not begin with the usual connection establishment. Deficiency: For completeness, Bro's event engine should generate another form of `partial_connection` event when a single endpoint becomes active (see `new_connection` below). This hasn't been implemented because our experience is network traffic often contains a great deal of ``crud'', which would lead to a large number of these really-partial events. However, by not providing the event handler, we miss an opportunity to detect certain forms of stealth scans until they begin to elicit some form of reply.

  [`connection_finished`] Generated when a connection has gracefully closed.

  [`connection_rejected`] Generated when a server rejects a connection attempt by a client.

  Note: This event is only generated as the client attempts to establish a connection. If the server instead accepts the connection and then later aborts it, a `connection_reset` event is generated (see below). This can happen, for example, due to use of TCP Wrappers.

  Note: Per the discussion above, a client attempting to connect to a server will result in one of `connection_attempt`, `connection_established`, or `connection_rejected`; they are mutually exclusive.

  [`connection_half_finished`] Generated when Bro sees one endpoint of a connection attempt to gracefully close the connection, but the other endpoint is in the `TCP_INACTIVE` state. This can happen due to split routing (§ ), in which Bro only sees one side of a connection.

  [`connection_reset`] Generated when one endpoint of an established connection terminates the connection abruptly by sending a TCP RST packet.

  [`connection_partial_close`] Generated when a previously inactive endpoint attempts to close a connection via a normal FIN handshake or an abort RST sequence. When it sends one of these packets, Bro waits `PARTIAL_CLOSE_INTERVAL` (an internal Bro variable set to 10 seconds) prior to generating the event, to give the other endpoint a chance to close the connection normally.

  [`connection_pending`] Generated for each still-open connection when Bro terminates.

##
The `tcp` analyzer

The general `tcp` analyzer lets you specify that you're interested in generic connection analysis for TCP. It simply `@load`'s `conn` and adds the following to `capture_filter`:

        tcp[13] & 0x7 != 0

which instructs Bro to capture all TCP SYN, FIN and RST packets; that is, the control packets that delineate the beginning (SYN) and end (FIN) or abnormal termination (RST) of a connection.

##
The `udp` analyzer

The general `udp` analyzer lets you specify that you're interested in generic connection analysis for UDP. It `@load`'s both `hot` and `conn`, and defines two event handlers:

  [``udp_request (u: connection)``] Invoked whenever a UDP packet is seen on the forward (request) direction of a UDP connection. See § for a discussion of how Bro defines UDP connections.

  The analyzer invokes `check_hot` with a mode of `CONN_ATTEMPTED` and then `record_connection` to generate a connection summary (necessary because Bro does not time out UDP connections, and hence cannot generate a connection-attempt-failed event).

  [``udp_reply (u: connection)``] Invoked whenever a UDP packet is seen on the reverse (reply) direction of a UDP connection. See § for a discussion of how Bro defines UDP connections.

  The analyzer invokes `check_hot` with a mode of `CONN_ESTABLISHED` and then again with a mode of `CONN_FINISHED` to cover the general case that the reply reflects that the connection was both established and is now complete. Finally, it invokes `record_connection` to generate a connection summary.

Note: The standard script does not update `capture_filter` to capture UDP traffic. Unlike for TCP, where there is a natural generic filter that captures only a subset of the traffic, the only natural UDP filter would be simply to capture all UDP traffic, and that can often be a huge load.

##
Connection summaries

The main output of `conn` is a one-line ASCII summary of each connection. By tradition, these summaries are written to a file with the name `red.`tag, where tag uniquely identifies the Bro session generating the logs. (```red`'' is mnemonic for ``reduced,'' from Bro's roots in performing protocol analysis for Internet traffic studies.)

The summaries are produced by the `record_connection` function, and have the following format:

> `<`start`>` `<`duration`>` `<`service`>` `<`state`>` `<`flags`>` `<`addl`>`

start
  corresponds to the connection's start time, as defined by `start_time`.

duration
  gives the connection's duration, as defined by `duration`.

service
  is the connection's service, as defined by `service`.

,
  give the number of bytes sent by the originator and responder, respectively. These correspond to the `size` fields of the corresponding `endpoint` records.

,
  correspond to the local and remote addresses that participated in the connection, respectively. The notion of which addresses are local is controlled by the `local_nets` global variable, if refined from its default value of empty. If `local_nets` has not been refined, then is the connection responder and is the connection originator.

  Note: The format and defaults for and are unintuitive; they reflect the use of Bro's predecessor for analyzing Internet traffic patterns, and have not been changed so as to maintain compatibility with old, archived connection summaries.

  Table 7.2: Summaries of connection states, as reported in `red` files.
  Symbol | Name | Meaning
  `}` | `S0` | Connection attempt seen, no reply.
  `>` | `S1` | Connection established, not terminated.
  `>` | `SF` | Normal establishment and termination. Note that this is the same symbol as for state `S1`. You can tell the two apart because for `S1` there will not be any byte counts in the summary, while for `SF` there will be.
  `[` | `REJ` | Connection attempt rejected.
  `}2` | `S2` | Connection established and close attempt by originator seen (but no reply from responder).
  `}3` | `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.
  `}]` | `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.
  `>h` | `SH` | Originator sent a SYN followed by a FIN, we never saw a SYN ACK from the responder (hence the connection was ``half" open).
  `<h` | `SHR` | Responder sent a SYN ACK followed by a FIN, we never saw a SYN from the originator.
  `?>?` | `OTH` | No SYN seen, just midstream traffic (a ``partial connection'' that was not later closed).

state
  reflects the state of the connection at the time the summary was written (which is usually either when the connection terminated, or when Bro terminated). The different states are summarized in Table 7.3.6. The ASCII Name given in the Table is what appears in the `red` file; it is returned by the `conn_state` function. The Symbol is used when generating human-readable versions of the file--see `hot-report`.

  For UDP connections, the analyzer reports connections for which both endpoints have been active as `SF`; those for which just the originator was active as `S0`; those for which just the responder was active as `SHR`; and those for which neither was active as `OTH` (this latter shouldn't happen!).

flags
  reports a set of additional binary state associated with the connection:

  `L`
    indicates that the connection was initiated locally, i.e., the host corresponding to initiated the connection. If `L` is missing, then the host corresponding to initiated the connection.

  `U`
    indicates the connection involved one of the networks listed in the `neighbor_nets` variable. The use of ```U`'' for this indication (rather than ```N`'', say) is historical, as for the most part is the whole notion of ``neighbor network.''

    Note that connection can have both `L` and `U` set (see next item).

  `X`
    is used to indicate that neither the ```L`'' or ```U`'' flags is associated with this connection. An explicit negative indication is needed to disambiguate the flags field from the subsequent addl field.

addl
  lists additional information associated with the connection, i.e., as defined by `addl`.

Putting all of this together, here is an example of a `red` connection summary:

    931803523.006848 54.3776 http 7320 38891 206.132.179.35 128.32.162.134 RSTO X %103

The connection began at timestamp 931803523.006848 (18:18:43 hours GMT on July 12, 1999; see the cf utility for how to determine this) and lasted 54.3776 seconds. The service was HTTP (presuambly; this conclusion is based just on the responder's use of port `80/tcp`). The originator sent 7,320 bytes, and the responder sent 38,891 bytes. Because the ```L`'' flag is absent, the connection was initiated by host 128.32.162.134, and the responding host was 206.132.179.35. When the summary was written, the connection was in the ```RSTO`'' state, i.e., after establishing the connection and transferring data, the originator had terminated it with a RST (this is unfortunately common for Web clients). The connection had neither the `L` or `U` flags associated with it, and there was additional information, summarized by the string ```%103`'' (see the `http` analyzer for an explanation of this information).

##
Connection functions

We finish our discussion of generic connection analysis with a brief summary of the different Bro functions provided by the `conn` analyzer:

  [``conn_size`(e: endpoint, is_tcp: bool): string``` ] returns a string giving either the number of bytes the endpoint sent during the given connection, or `"?"` if from the connection state this can't be determined. The `is_tcp` parameter is needed so that the function can inspect the endpoint's state to determine whether the connection was closed.

  [``conn_state`(c: connection, is_tcp: bool): string``` ] returns the name associated with the connection's state, as given in Table 7.3.6.

  [``determine_service`(c: connection): bool``` ] sets the `service` field of the given connection, using `port_names`. If you are using the `ftp` analyzer, then it knows about FTP data connections and maps them to `port_names[20/tcp]`, i.e., `"ftp-data"`.

  [``full_id_string`(c: connection): string``` ] returns a string identifying the connection in one of the two following forms. If the connection is in state `S0`, `S1`, or `REJ`, then no data has been transferred,7.1 and the format is:

  > `<`state`>` `/``<`service`>` `<`addl`>`

  where is the IP address of the originator (`$id$orig_h`), state is as given in the Symbol column of Table 7.3.6, is the IP address of the responder (`$id$resp_h`), service gives the application service (`$service`) as set by `determine_service`, and addl is the contents of the `$addl` field (which may be an empty string).

  Note that the ephemeral port used by the originator is not reported. If you want to display it, use `id_string`.

  So, for example:

          128.3.6.55 > 131.243.88.10/telnet "luser"

  identifies a connection originated by `128.3.6.55` to `131.243.88.10`'s Telnet server, for which the additional associated information is `"luser"`, the username successfully used during the authentication dialog as determined by the `login` analyzer. From Table 7.3.6 we see that the connection must be in state `S1`, as that's the only state of `S0`, `S1`, or `REJ` that has a `>` symbol. (We can tell it's not in state `SF` because the format used for that state differs--see below.)

  For connections in other states, Bro has size and duration information available, and the format returned by `full_id_string` is:

  > `b` `<`state`>` `/``<`service`>` `b` `s` `<`addl`>`

  where , , state, service, and addl are as before, and give the number of bytes transmitted so far by the originator to the responder and vice versa, and gives the duration of the connection in seconds (reported with one decimal place) so far.

  An example of this second format is:

          128.3.6.55 63b > 131.243.88.10/telnet 391b 39.1s "luser"

  which reflects the same connection as before, but now `128.3.6.55` has transmitted 63 bytes to `131.243.88.10`, which has transmitted 391 bytes in response, and the connection has been active for 39.1 seconds. The ```>`'' indicates that the connection is in state `SF`.

  [``id_string`(id: conn_id): string``` ] returns a string identifying the connection by its address/port quadruple. Regardless of the connection's state, the format is:

  > `/` `>` `/`

  where and are the originator and responder addresses, respectively, and and are representations of the originator and responder ports as returned by the `port-name` module, i.e., either ```<`number`>/<``tcp` or `udp``>`'' or a string like ```http`'' for a well-known port such as `80/tcp`.

  An example:

          128.3.6.55/2244 > 131.243.88.10/telnet

  Note, `id_string` is implemented using a pair of calls to `endpoint_id`.

  Deficiency: It would be convenient to have a form of `id_string` that can incorporate a notion of directionality, for example `128.3.6.55/2244 < 131.243.88.10/telnet` to indicate the same connection as before, but referring specifically to the flow from responder to originator in that connection (indicated by using ```<`'' instead of ```>`'').

  [``log_hot_conn`(c: connection)``` ] logs a real-time alert of the form:

  > hot: `<`connection-id`>`

  where connection-id is the format returned by `full_id_string`. `log_hot_conn` keeps track of which connections it has logged and will not log the same connection more than once.

  [``record_connection`(c: connection, disposition: string)``` ] Generates a connection summary to the `red` file in the format described in § . If the connection's `$hot` field is positive, then also logs the connection using `log_hot_conn`. The `disposition` is a text description of the connection's state, such as `"attempt"` or `"half_finished"`; it is not presently used.

  [``service_name`(c: connection): string``` ] returns a string describing the service associated with the connection, computed as follows. If the responder port (`$id$resp_p`), , is well-known, that is, in the `port_names` table, then 's entry in the table is returned (such as `"http"` for TCP port 80). Otherwise, for TCP connections, if the responder port is less than 1024, then `priv-` is returned, otherwise `other-`. For UDP connections, the corresponding service names are `upriv-` and `uother-`.

  [``terminate_connection`(c: connection)``` ] Attempts to terminate the given connection using the `rst` utility in the current directory. It does not check to see whether the utility is actually present, so an unaesthetic shell error will appear if the utility is not available.

  `rst` terminates connections by forging RST packets. It is not presently distributed with Bro, due to its potential for disruptive use.

  If Bro is reading a trace file rather than live network traffic, then `terminate_connection` logs the `rst` invocation but does not actually invoke the utility. In either case, it finishes by logging that the connection is being terminated.

#
Site-specific information

The `site` analyzer is not actually an analyzer but simply a set of global variables (and one function) used to define a site's basic topological information.

##
Site variables

The `site` module defines the following variables, all redefinable:

  [``local_nets : set[net]``] Defines which `net`'s Bro should consider as reflecting a local address.

  Default: empty.

  [``local_16_nets : set[net]``] Defines which /16 prefixes Bro should consider as reflecting a local address. Deficiency: Bro currently is inconsistent regarding when it consults `local_nets` versus `local_16_nets`, so you should ensure that this variable and the previous one are always consistent.

  Default: empty.

  [``local_24_nets : set[net]``] The same, but for /24 addresses.

  Default: empty.

  [``neighbor_nets : set[net]``] Defines which `net`'s Bro should consider as reflecting a ``neighbor.'' Neighbors networks can be treated specially in some policies, distinct from other non-local addresses. In particular, `drop_address` will not drop connectivity to an address belonging to a neighbor.

  The notion is somewhat historical, as is the use of ```U`'' to mark neighbors in connection summaries (§ ).

  Default: empty.

  [``neighbor_16_nets : set[addr]``] Defines which /16 addresses Bro should consider as reflecting a neighbor; the only use of this variable in the standard scripts is that a scan originating from an address with one of these prefixes will not be dropped (§ ). Deficiency: The name is poorly chosen and should be changed to better reflect this use. Deficiency: In addition, this variable should be kept consistent with `neighbor_nets`, until the fine day when the processing is rectified to only use one variable.

  Default: empty.

  [``neighbor_24_nets : set[net]``] The same, but for /24 addresses.

  Default: empty.

##
Site-specific functions

Currently, the `site` module only defines one function:

  [``is_local_addr`(a: addr): bool``` ] returns true if the given address belongs to one of the ``local'' networks, false otherwise. Currently, the test is made by masking the address to /16 and /24 and comparing it to `local_16_nets` and `local_24_nets`.

#
The `hot` Analyzer

The standard `hot` script defines policy relating to fairly generic notions of allowed and prohibited connections. It defines a number of variables that you will need to refine to customize your site's policies. It also provides two functions for checking connections against the policies, which can be used by other of the standard scripts.

##
`hot` variables

The standard `hot` script defines the following variables, all redefinable:

  [``same_local_net_is_spoof : bool``] If true, then a connection with a local originator address and a local responder address is considered by `check_spoof` to have been spoofed. Deficiency: The name is poorly chosen (and may be changed in the future) to something more accurate like `both_local_nets_is_spoof`.

  In general, you want to use true for a Bro that is monitoring Internet access links (DMZs) and false for internal monitors.

  Default: `F`.

  [``allow_spoof_services : set[port]``] Defines a set of services (responder ports) for which Bro should not generate alerts if it sees apparent spoofed traffic.

  Default: `110/tcp` (POP version 3; [RFC1939]). This default was chosen because in our experience one common form of benign spoof is an off-site laptop attempting to read mail while still configured to use its on-site address.

  [``allow_pairs : set[addr, addr]``] Defines pairs of source and destination addresses for which the source is allowed to connect to the destination. The intent with this variable is that the source or destination address will be a sensitive host (such as defined with `hot_srcs` or `hot_dsts`), for which this particular access should be allowed.

  Default: empty.

  [``allow_16_net_pairs : set[addr, addr]``] Defines pairs of source and destination /16 networks for which the source is allowed to connect to the destination, similar to `allow_pairs`. Note: The set is defined in terms of `addr`'s and not `net`'s. So, for example, rather than specifying `128.32.`, which is a `net` constant, you'd use `128.32.0.0` (an `addr` constant).

  Default: empty.

  [``hot_srcs : table[addr] of string``] Defines source addresses that should be considered ``hot''. A successfully established connection from such a source address is logged, unless one of the access exception variables such as `allow_pairs` also matches the connection. The value of the table gives an explanatory message as to why the source is hot; for example, `"known attacker site"`. Note: This value is not currently used, though it aids in documenting the policy script.

  Default: empty.

  Example: redefining `hot_srcs` using

      redef hot_srcs: table[addr] of string = {
          [ph33r.the.eleet.com] = "script kideez",
      };

  would result in Bro alerting on any traffic coming `ph33r.the.eleet.com`.

  [``hot_dsts : table[addr] of string``] Same as `hot_srcs`, except for destination addresses.

  Default: empty.

  [``hot_src_24nets : table[addr] of string``] Defines /24 source networks should be considered ``hot,'' similar to `hot_srcs`. Deficiency: Other network masks, particularly /16, should be provided.

  Default: empty.

  Example: redefining `hot_src_24nets` using

      redef hot_src_24nets: table[addr] of string = {
          [198.81.129.0] = "CIA incoming!",
      };

  would result in Bro alerting on any traffic coming from the `198.81.129/24` network.

  [``hot_dst_24nets : table[addr] of string``] same as `hot_src_24nets`, except for destination networks.

  Default: empty.

  [``allow_services : set[port]``] Defines a set of services that are always allowed, regardless of whether the source or destination address is ``hot.''

  Default: `ssh`, `http`, `gopher` `ident`, `smtp`, `20/tcp` (FTP data).

  Note: The defaults are a bit unusual. They are intended for a quite open site with many services.

  [``allow_services_to : set[addr, port]``] Defines a set of services that are always allowed if the server is the given host, regardless of whether the source or destination address is ``hot.''

  Default: empty.

  Example: redefining `allow_services_to` using

      redef allow_services_to: set[addr, port] += {
          [ns.mydomain.com, [domain, 123/tcp]],
      } &redef;

  would result in Bro not alerting on any TCP DNS or NTP traffic heading to `ns.mydomain.com`. You might add this if `ns.mydomain.com` is also in `hot_dsts`, because in general you want to consider any access (other than DNS or NTP) as sensitive.

  [``allow_services_pairs : set[addr, addr, port]``] Defines a set of services that are always allowed if the connection originator is the first address and the responder (server) the second address.

  Default: empty.

  Example: redefining `allow_services_pairs` using

      redef allow_services_pairs: set[addr, addr, port] += {
          [ns2.mydomain.com, ns.mydomain.com, [domain, 123/tcp]],
      } &redef;

  would result in Bro not alerting on any TCP DNS or NTP traffic initiated from `ns2.mydomain.com` to `ns.mydomain.com`.

  [``flag_successful_service : table[port] of string``] The opposite of `allow_services`. Defines a set of services that should always be flagged as sensitive, even if neither the source nor the destination address is ``hot.'' The `string` value in the table gives the reason for why the service is considered hot. Note: Bro currently does not use these explanatory messages.

  Default: `31337/tcp` (a popular backdoor because in stylized lettering it spells `ELEET`) and `2766/tcp` (the Solaris `listen` service, in our experience rarely used legitimately in wide-area traffic).

  Note: Bro can flag these services erroneously when a server happens to run a different service on the same port. For example, if you're not running the FTP analyzer, then Bro won't know that FTP data connections using ephemeral ports in fact belong to legitimate FTP traffic, and will flag any that coincide with these services. A related problem arises when a user has configured their SSH access to tunnel FTP control channels through the FTP connection, but not the corresponding data connections (so they don't pay the expense of encrypting the data transfers), so again Bro can't recognize that the ephemeral ports used for the data connections does not reflect the presumed sensitive service.

  Example: redefining `flag_successful_service` using

      redef flag_successful_service: table[port] of string += {
              [1524/tcp] = "popular backdoor",
      };

  would result in Bro also alerting on any successful connection to a server running on TCP port 1524.

  [``flag_successful_inbound_service : table[port] of string``] The same as `flag_
  [0]successful_
  [0]service`, except only applies to connections with a remote initiator and a local responder (determined by finding the responder address in `local_nets`).

  Default: `1524/tcp` (`ingreslock`, a popular backdoor because an attacker can place an entry for the backdoor in /etc/inetd.conf using a service name rather than a raw port number, and hence more likely to appear legitimate to casual inspection). Note: There's no compelling reason why `ingreslock` is in this table rather than the more general `flag_successful_service`, though it does tend to result in a few more false hits than the others, presumably because it's a lower port number, and hence more likely on some systems to be chosen for an ephemeral port. `ingreslock`

  Note: Symmetry would call for `flag_successful_outbound_service`. This hasn't been implemented in Bro yet simply because the Bro development site has a threat model structured primarily around external threats.

  [``terminate_successful_inbound_service : table[port] of string``] The same as `flag_
  [0]successful_
  [0]inbound_
  [0]service`, except invokes `terminate_connection` in an attempt to terminate the connection.

  Default: empty.

  Note: As for `flag_
  [0]successful_
  [0]inbound_
  [0]service`, it would be symmetric to have `terminate_
  [0]successful_
  [0]outbound_
  [0]service`, and also to have a more general `terminate_
  [0]successful_
  [0]service`.

  [``flag_rejected_service : table[port] of string``] Similar to `flag_successful_service`, except applies to connections that a server rejects. For example, you could detect a particular, failed Linux mountd attack by adding `10752/tcp` to this table, since that happens to be the port used by the commonly available version of the exploit for its backdoor if the attack succeeds. Note: You would of course likely also want to put `10752/tcp` in `flag_successful_service`; or put the entire `flag_rejected_service` table into `flag_successful_service`, as discussed in § .

  Default: none.

  Deficiency: It might make sense to have `flag_attempted_service`, which doesn't require that a server actively reject the connection, but Bro doesn't currently have this.

##
`hot` functions

The `hot` module defines two functions for external use:

  [``check_spoof`(c: connection): bool``` ] checks the originator and responder addresses of the given connection to determine if they are both local (and the connection is not explicitly allowed in `allow_spoof_services`). If so, and if `same_local_net_is_spoof` is true, then marks the connection as ``hot''.

  The function also checks for a specific denial of service attack, the ``Land'' attack, in which the addresses are the same and so are the ports. If so, then it generates a `conn_weird` event with a name of `"Land_attack"`. It makes this check even if `same_local_net_is_spoof` is false.

  Returns: true if the connection is now hot (or was upon entry), false otherwise.

  [``check_hot`(c: connection, state: count): bool``` ] checks the given connection against the various policy variables discussed above, and bumps the connection's `hot` field if it matches the policies for being sensitive, and does not match the various exceptions. It also uses `check_spoof` to see if the connection reflects a possible spoofing attack; and terminates the connection if `terminate_successful_service` indicates so.

  Table 7.3: Different connection states to use when calling `check_hot`.
  State | Meaning | Tests
  `CONN_ATTEMPTED` | Connection attempted, no reply seen. Note that you should also use this value for scans with indeterminant state, such as possible stealth scans. For example, `connection_half_finished` does this. | `check_spoof`.
  `CONN_ESTABLISHED` | Connection established. Also used for connections apparently established, per `partial_connection`. | `check_spoof`, `flag_successful_service`, `flag_successful_inbound_ [0]service`, `allow_services_to`, `terminate_successful_ [0]inbound_ [0]service`.
  `APPL_ESTABLISHED` | The connection has reached application-layer establishment. For example, for Telnet or Rlogin, this is after the user has authenticated. | `allow_services_to`, `allow_service_pairs`, `allow_pairs`, `allow_16_net_pairs`, `hot_srcs`, `hot_dsts`, `hot_src_24nets`, `hot_ [0]dst_ [0]24nets`.
  `CONN_FINISHED` | The connection has finished, either cleanly or abnormally (for example, `connection_reset`). | Same as `APPL_ESTABLISHED`, if the connection exchanged non-zero amounts of data in both directions, and if the service wasn't one of the ones that generates `APPL_ESTABLISHED`.
  `CONN_REJECTED` | The connection attempt was rejected by the server. | `check_spoof`, `flag_rejected_service`.

  The caller indicates the connection's state in the second parameter to the function, using one of the values given in Table 7.5.2. As noted in the Table, the processing differs depending on the state.

  In general, the pattern is to make one call when the connection is first seen, either `CONN_ATTEMPTED`, `CONN_ESTABLISHED`, or `CONN_REJECTED`. If the application is one for which connections should only be considered ``established'' after a successful pre-exchange between originator and responder, then a subsequent call is made with a state of `APPL_ESTABLISHED`. The idea here is to provide a way to filter out what are in fact not really successful connections so that they are not analyzed in terms of successful service. Finally, for services that don't use `APPL_ESTABLISHED`, a call is made instead when the connection finishes for some reason, using state `CONN_FINISHED`. Note: This approach delays alerting until the connection is over, which might be later than you want, in which case you may need to edit `check_hot` to provide the desired functionality.

  Returns: true if the connection is now hot (or was upon entry), false otherwise.

#
The `scan` Analyzer

The `scan` analyzer detects connection attempts to numerous machines (address scanning), connection attempts to many different services on the same machine (port scanning), and attempts to access many different accounts (password guessing). The basic methodology is to use tables to keep track of the distinct addresses and ports to which a given host attempts to connect, and to trigger alerts when either of these reaches a specified size. Deficiency: As currently written, the analyzer will not detect distributed scans, i.e., when many sites are used to probe individually just a few, but together a large number, of ports or addresses.

A powerful technique that Bro potentially provides is dropping border connectivity with remote scanning sites, though you must supply the magic script to talk with your router and effect the block. See `drop_address` below for a discussion of the interface provided. Note: Naturally, providing this capability means you might become vulnerable to denial-of-service attacks in which spoofed packets are used in an attempt to trigger a block of a site to which you want to have access.

##
`scan` variables

In addition to internal variables for its bookkeeping, the analyzer provides the following redefinable variables:

  [``report_peer_scan : set[count]``] Generate a log message whenever a remote host (as determined by `is_local_addr`) has attempted to connect to the given number of distinct hosts.

  Default: `{ 100, 1000, 10000, }`. So, for example, if a remote host attempts to connect to 3,500 different local hosts, a report will be generated when it makes the 100th attempt, and another when it makes the 1,000th attempt.

  [``report_outbound_peer_scan : set[count]``] The same as `report_peer_scan`, except for connections initiated locally.

  Default: `{ 1000, 10000, }`.

  [``possible_port_scan_thresh : count``] Initially, port scan detection is done based on how many different ports a given host connects to, regardless of on which hosts. Once this threshold is reached, however, then the analyzer begins tracking ports accessed per-server, which is important for reducing false positives. Note: The reason this variable exists is because it is very expensive to track per-server ports accessed for every active host; this variable limits such tracking to only active hosts contacting a significant number of different ports.

  Default: `25`.

  [``report_accounts_tried : set[count]``] Whenever a remote host has attempted to access a number of local accounts present in this set, generate a log message. Each distinct username/password pair is considered a different access.

  Default: `{ 25, 100, 500, }`.

  [``report_remote_accounts_tried : set[count]``] The same, except for access to remote accounts rather than local ones.

  Default: `{ 100, 500, }`.

  [``skip_accounts_tried : set[addr]``] Do not do bookkeeping for account attempts for the given hosts.

  Default: empty.

  [``skip_outbound_services : set[port]``] Do not do outbound-scanning bookkeeping for connections involving the given services.

  Default: `allow_services`, `ftp`, `addl_web` (see next item).

  [``addl_web : set[port]``] Additional ports that should be considered as Web traffic (and hence skipped for outbound-scan bookkeeping).

  Default: `{ 81/tcp, 443/tcp, 8000/tcp, 8001/tcp, 8080/tcp, }`.

  [``skip_scan_sources : set[addr]``] Hosts that are allowed to address-scan without complaint.

  Default: `scooter.pa-x.dec.com`, `scooter2.av.pa-x.dec.com` (AltaVista crawlers; you get the idea.)

  [``skip_scan_nets_24 : set[addr, port]``] /24 networks that are allowed to address scan for the given port without complaint.

  Default: empty.

  [``can_drop_connectivity : bool``] True if the Bro has the capability of dropping connectivity, per `drop_address`.

  Default: false.

  [``shut_down_scans : set[port]``] Scans of these ports trigger connectivity-dropping (if the Bro is capable of dropping connectivity), unless `shut_down_all_scans` is defined (next item).

  Default: empty.

  [``shut_down_all_scans : bool``] Ignore `shut_down_scans` and simply drop all scans regardless of service.

  Default: false.

  [``shut_down_thresh : count``] Shut down connectivity after a host has scanned this many addresses.`

  Default: `100`.

  [``never_shut_down : set[addr]``] Purported scans from these addresses are never shut down.

  Default: the root name servers (`a.root-servers.net` through `m.root-servers.net`).

##
`scan` functions

The standard `scan` script provides the following functions:

  [``drop_address`(a: addr, msg: string)``` ] Drops external connectivity to the given address and logs a notification using the given message.

  Dropping connectivity requires all of the following to be true:

  - `can_drop_connectivity` is true.
  - The address is neither local nor a neighbor (§ ).
  - The address is not in `never_shut_down`.
  If these checks succeed, then the script simply attempts to invoke a shell script drop-connectivity with a single argument, the IP address to block. It is up to you to provide the script, using whatever interface to your router/firewall you have available.

  The function does not return a value.

  [``check_scan`(c: connection, established: bool, reverse: bool): bool``` ] Updates the analyzer's internal bookkeeping on the basis of the new connection `c`. If `established` is true, then the connection was successfully established, otherwise not. If `reverse` is true, then the function should consider the originator/responder fields in the connection's record as reversed. Note: This last is needed for some unusual new connections that may reflect stealth scanning. For example, when the event engine sees a SYN-ack without a corresponding SYN, it instantiates a new connection with an assumption that the SYN-ack came from the responder (and it missed the initial SYN either due to split routing (§ ), a packet drop (§ ), or Bro having started running after the initial SYN was sent).

  If the originating host's activity matches the policy defined by the variables above, then the analyzer logs this fact, and possibly attempts to drop connectivity to the originating host. The function also schedules an event for 24 hours in the future (or when Bro terminates) to generate a summary of the scanning activity (so if the host continues scanning, you get a report on how many hosts it wound up scanning). Deficiency: This time interval should be selectable.

  Note: Purported scans of the FTP data port (`20/tcp`) or the `ident` service (`113/tcp`) are never reported or dropped, as experience has shown they yield too many false hits.

  The function does not return a value.

##
`scan` event handlers

The standard `scan` script defines one event handler:

  [``account_tried (c: connection, user: string, passwd: string)``] The given connection made an attempt to access the given username and password. Each distinct username/password pair is considered a new access. The event handler generates a log message if the access matches the logging policy outlined above.

  Note: `account_tried` events are generated by `login` and `ftp` analyzers.

#
The `port-name` Module

The `port-name` utility module provides one redefinable variable and one callable function:

  [``port_names : table[port] of string``] Maps TCP/UDP ports to names for the services associated with those ports. For example, `80/tcp` maps to `"http"`. These names are used by the `conn` analyzer when generating connection logs (§ ).

  [``endpoint_id`(h: addr, p: port): string``` ] Returns a printable form of the given address/port connection endpoint. The format is either `<`address`>/<`service-name`>` or `<`address`>/<`port-number`>` depending on whether the port appears in `port_names`.

#
The `mt` Module

The `mt` module is intended to provide a convenient way to run (almost) all of the analyzers. It `@load`'s the following other modules and analyzers: `log`, `dns`, `hot`, `port-name`, `frag`, `tcp`, `scan`, `weird`, `finger`, `ident`, `ftp`, `login` and `portmapper`. So you can run Bro using bro -i in0 mt to have it analyze traffic on interface in0 using the above analyzers (§ ); or you can `@load` `mt` to load in the above analyzers.

Note: The `mt` analyzer doesn't load `http` (because it can prove a very high load for many sites) nor experimental analyzers such as `stepping` or `backdoor`.

#
The `log` Module

The `log` utility module redefines a single variable:

  [``bro_log_file : file``] A special Bro variable used internally to specify a file where Bro should record messages logged by `log` statements (as well as generating real-time alerts via syslog).

  Default: if the `$BRO_ID` environment variable is defined, then `log.`<`$BRO_ID`>``, otherwise `bro.log`.

  Note: This value is slightly different than that returned by `open_log_file`, because the latter would return `log` if `$BRO_ID` wasn't defined, and that name seems too easy to confuse with other uses.

  See § for further discussion.

If you do not include this module, then Bro records log messages to stderr.

Figure 7.4: Sample definition of `log_hook`

You can also control Bro's log processing by defining the special function `log_hook`. It takes a single argument, `msg: string`, the message in a just-executed `log` statement, and returns a boolean value: true if Bro should indeed log the message, false if not. For example, Figure 7.9 shows a definition of `log_hook` that checks each log message to see whether the same text has been logged before. It only logs the first instance of a message. If a message appears at least five times, then it schedules a future `log_summary` event for 5 minutes in the future; the purpose of this event is to summarize the total number of times the message has appeared at that point in time.

#
The `active` Module

The `active` utility module provides a single, non-redefinable variable that holds information about active connections:

  [``active_conn : table[conn_id] of connection``] Indexed by a `conn_id` (Figure 7.3.1) giving the originator/responder addresses/ports, returns the connection's `connection` record. As usual, accessing the table with a non-existing index results in a run-time error, so you should first test for the presence of the index using the `in` operator.

  Default: empty.

This functionality is quite similar to that of the `active_connection` function, and Deficiency: arguably this module should be removed in favor of the function. It does, however, provide a useful example of maintaining bookkeeping by defining additional handlers for events that already have handlers elsewhere.

#
The `demux` Module

The `demux` utility module provides a single function:

  [``demux_conn`(id: conn_id, tag: string, otag: string, rtag: string): bool``` ] Instructs Bro to write (``demultiplex'') the contents of the connection with the given `id` to a pair of files whose names are constructed out of `tag`, `otag`, and `rtag`, as follows.

  The originator-to-responder direction of the connection goes into a file named:

  > `<`otag`>.<` tag`>.<` orig-addr`>.<` orig-port`>-<` resp-addr`>.<` resp-port`>`

  and the other direction in:

  > `<`rtag`>.<` tag`>.<` resp-addr`>.<` resp-port`>-<` orig-addr`>.<` orig-port`>`

  Accordingly, tag can be used to associate a unique label with the pair of files, while otag and rtag provide distinct labels for the two directions.

  If Bro is already demuxing the connection, or if the connection is not active, then nothing happens, and the function returns false. Otherwise, it returns true.

Bro places demuxed streams in a directory defined by the redefinable global `demux_dir`, which defaults in the usual fashion to `open_log_file("xscript")`.

Deficiency: Experience has shown that it would be highly convenient if Bro would demultiplex the entire connection contents into the files, instead of just the part of the connection seen subsequently after the call to `demux_conn`. One way to do this would be for `demux_conn` to offset the contents in the file by the current stream position, and then to invoke a utility tool that goes through the Bro output trace file (§ ) and copies the contents up to the current stream position to the front of the file. This utility tool might even be another instance of Bro running with suitable arguments.

#
The `dns` Module

The `dns` module deals with Bro's internal mapping of hostnames to/from IP addresses. Deficiency: There is no DNS protocol analyzer available at present. Furthermore, Deficiency: the lookup mechanisms discussed here are not available to the Bro script writer, other than implicitly by using hostnames in lieu of addresses in variable initializations (§ ).

The module's function is to handle different events that can occur when Bro resolves hostnames upon startup. Bro maintains its own cache of DNS information which persists across invocations of Bro on the same machine and by the same user. The role of the cache is to allow Bro to resolve hostnames even in the face of DNS outages; the philosophy is that it's better to use old addresses than none at all, and this helps harden Bro against attacks in which the attacker causes DNS outages in order to prevent Bro from resolving particular sensitive hostnames (e.g., `hot_srcs`). The cache is stored in the file ```.bro-dns-cache`'' in the user's home directory. You can delete this file whenever you want, for example to purge out old entries no longer needed, and Bro will recreate it next time it's invoked using `-P`.

Currently, all of the event handlers are invoked upon comparing the results of a new attempt to look up a name or an address versus the results obtained the last time Bro did the lookup. When Bro looks up a name for the first time, no events are generated.

Also, Bro currently only looks up hostnames to map them to addresses. It does not perform inverse lookups.

##
The `dns_mapping` record

Figure 7.5: Definition of the `dns_mapping` record.

All of the events handled by the module include at least one record of DNS mapping information, defined by the `dns_mapping` type shown in Figure 7.12.1. The corresponding fields are:

  [`creation_time`] When the mapping was created.

  [`req_host`] The hostname looked up, or an empty string if this was not a hostname lookup.

  [`req_addr`] The address looked up (reverse lookup), or `0.0.0.0` if this was not an address lookup.

  [`valid`] True if an answer was received for a lookup (even if the answer was that the request name or address does not exist in the DNS).

  [`hostname`] The hostname answer in response to an address lookup, or the string `"`<`none`>"`` if an answer was received but it indicated there was no PTR record for the given address.

  [`addrs`] A set of addresses in response to a hostname lookup. Empty if an answer was received but it indicated that there was no A record for the given hostname.

##
`dns` variables

The modules provides one redefinable variable:

  [``dns_interesting_changes : set[string]``] The different DNS events have names associated with them. If the name is present in this set, then the event will be logged, otherwise not.

  One exception to this list is that DNS changes involving the loopback address `127.0.0.1` are always considered log-worthy, since they may reflect DNS corruption.

  Default: `{ "unverified", "old name", "new name", "mapping", }`.

##
`dns` event handlers

The DNS module supplies the following event handlers:

  [``dns_mapping_valid (dm: dns_mapping)``] The given request was looked up and it was identical to its previous mapping.

  [``dns_mapping_unverified (dm: dns_mapping)``] The given request was looked up but no answer came back.

  [``dns_mapping_new_name (dm: dns_mapping)``] In the past, the given address did not resolve to a hostname; this time, it did.

  [``dns_mapping_lost_name (dm: dns_mapping)``] In the past, the given address resolved to a hostname; now, that name has gone away. (An answer was received, but it stated that there is no hostname corresponding to the given address.)

  [``dns_mapping_name_changed (old_dm: dns_mapping, new_dm: dns_mapping)``] The name returned this time for the given address differs from the name returned in the past.

  [``dns_mapping_altered (dm: dns_mapping, old_addrs: set[addr], new_addrs: set[addr])``] The addresses associated with the given hostname have changed. Those in `old_addrs` used to be part of the set returned for the name, but aren't any more; while those in `new_addrs` didn't used to be, but now are. There may also be some unchanged addresses, which are those in `dm$addrs` but not in `new_addrs`.

#
The `finger` Analyzer

The `finger` analyzer processes traffic associated with the Finger service [RFC1288]. Bro instantiates a `finger` analyzer for any connection with service port `79/tcp` (if you `@load` the finger analyzer in your script, or define your own `finger_request` or `finger_reply` handlers, of course).

The analyzer uses a capture filter of ```port finger`'' (§ ).

In the past, attackers often used Finger requests to obtain information about a site's users, and sometimes to launch attacks of various forms (buffer overflows, in particular). In our experience, exploitation of the service has greatly diminished over the past years (no doubt in part to the service being increasingly turned off, or prohibited by firewalls). Now it is only rarely associated with an attack.

##
`finger` variables

The standard script defines two redefinable variables:

  [``hot_names : set[string]``] A list of usernames that should be considered sensitive (log-worthy) if included in a Finger request.

  Default: `{ "root", "lp", "uucp", "nuucp", "demos", "operator", "sync", "guest", "visitor", }`.

  [``max_request_length : count``] The largest reasonable request size (used to flag possible buffer overflow attacks). Bro marks a connection as ``hot'' if its request exceeds this length, and truncates its logging of the request to this many bytes, followed by `"..."`.

  Default: `80`.

##
`finger` event handlers

The standard script defines one event handler:

  [``finger_request (c: connection, request: string, full: bool)``] Invoked upon connection `c` having made the request `request`. The `full` flag is true if the request included the ``long format'' option (which the event engine will have removed from the request).

  The standard script flags long requests and truncates them as noted above, and then checks whether the request is for a name in `hot_names`. It then formats the request either by placing double quotation marks around it, or, if the request was empty--indicating a request for information on all users--the request is changed to the string `ALL` with no quotes around it.

  If the originator already made a request, then this additional request is placed in parentheses (though multiple requests violate the Finger protocol). If the request was for the `full` format, then the text ```(/W)`'' is appended to the request. Finally, the request is appended to the connection's `addl` field.

The event engine generates an additional event that the predefined `finger` script does not handle:

  [``finger_reply (c: connection, reply_line: string)``] Generated for each line of text sent in response to the originator's request.

#
The `frag` Module

The `frag` utility module simply refines the capture filter (§ ) so that Bro will capture and reassemble IP fragments. Bro reassembles any fragments it receives; but normally it doesn't receive any, except the beginnings of TCP fragments (see the `tcp` module), and UDP port 111 (per the `portmapper` module).

So, to make Bro do fragment reassembly, you simply use ```@load` `frag`''. It effects this by adding:

        (ip[6:2] & 0x3fff != 0) and tcp

to the filter. The first part of this expression matches all IP fragments, while the second restricts those matched to TCP traffic. We would like to use:

        (ip[6:2] & 0x3fff != 0) and (tcp or udp port 111)

to also include portmapper fragments, but that won't work--the port numbers will only be present in the first fragment, so the packet filter won't recognize the subsequent fragments as belonging to a UDP port 111 packet, and will fail to capture them.

Note: Alternatively, we might be tempted to use ```(tcp or udp)`'' and so capture all UDP fragments, including port 111. This would work in principle, but in practice can capture very high volumes of traffic due to NFS traffic, which can send all of its file data in UDP fragments.

#
The `hot-ids` Module

The `hot-ids` module defines a number of redefinable variables that specify usernames Bro should consider sensitive:

  [``forbidden_ids : set[string]``] lists usernames that should never be used. If Bro detects use of one, it will attempt to terminate the corresponding connection.

  Default: `{ "uucp", "daemon", "rewt", "nuucp", "EZsetup", "OutOfBox", "4Dgifts", "ezsetup", "outofbox", "4dgifts", "sgiweb", }`. All of these correspond to accounts that some systems have enabled by default (with well-known passwords), except for `"rewt"`, which corresponds to a username often used by (weenie) attackers.

  Deficiency: The repeated definitions such as `"EZsetup"` and `"ezsetup"` reflect that this variable is a `set` and not a `pattern`. Consequently, the exact username must appear in it (with a pattern, we could use character classes to match both upper and lower case).

  [``forbidden_ids_if_no_password : set[string]``] Same as `forbidden_ids` except only considered forbidden if the login succeeded with an empty password.

  Default: `"lp"`, a default passwordless IRIX account.

  [``forbidden_id_patterns : pattern``] A pattern giving user ids that should be considered forbidden. Deficiency: This pattern is currently only used to check Telnet/Rlogin user ids, not ids seen in other contexts, such as FTP sessions.

  Default: `/(y[o0]u)(r|ar[e3])([o0]wn.*)/`, a particularly egregious style of username of which we've observed variants in different break-ins.

  [``always_hot_ids : set[string]``] A list of usernames that should always be considered sensitive, though not necessarily so sensitive that they should be terminated whenever used.

  Default: `{ "lp", "warez", "demos", forbidden_ids, }`. The `"lp"` and `"demos"` accounts are specified here rather than `forbidden_ids` because it's possible that they might be used for legitimate accounts. `"warez"` (for ``wares'', i.e., bootlegged software) is listed because its use likely constitutes a policy violation, not a security violation.

  Note: `forbidden_ids` is incorporated into `always_hot_ids` to avoid replicating the list of particularly sensitive ids by listing it twice and risking inconsistencies.

  [``hot_ids : set[string]``] User ids that generate alerts if the user logs in successfully.

  Default: `{ "root", "system", always_hot_ids, }`. The ones included in addition to `always_hot_ids` are only considered sensitive if the user logs in successfully.

#
The `ftp` Analyzer

The `ftp` analyzer processes traffic associated with the FTP file transfer service [RFC959]. Bro instantiates an `ftp` analyzer for any connection with service port `21/tcp`, providing you have loaded the `ftp` analyzer, or defined a handler for `ftp_request` or `ftp_reply`.

The analyzer uses a capture filter of ```port ftp`'' (§ ). It generates summaries of FTP sessions; looks for sensitive usernames, access to sensitive files, and possible FTP ``bounce'' attacks, in which the host specified in a ```PORT`'' or ```PASV`'' directive does not correspond to the host sending the directive; or in which a different host than the server (client) connects to the endpoint specified in a `PORT` (`PASV`) directive.

##
The `ftp_session_info` record

Figure 7.6: Definition of the `ftp_session_info` record.

The main data structure managed by the `ftp` analyzer is a collection of `ftp_session_info` records, where the record type is shown in Figure 7.16.1. The corresponding fields are:

  [`id`] The unique session identifier assigned to this session. Sessions are numbered starting at `1` and incrementing with each new session.

  [`user`] The username associated with this session (from the initial FTP authentication dialog), or an empty string if not yet determined.

  [`request`] The pending request, if the client has issued any. Ordinarily there would be at most one pending request, but a client can in fact send multiple requests to the server all at once, and an attacker could do so attempting to confuse the analyzer into mismatching responses with requests, or simply forgetting about previous requests.

  [`num_requests`] A count of how many requests are currently pending.

  [`request_t`] The time at which the pending request was issued.

  [`log_if_not_denied`] If true, then when the reply to the current request comes in, Bro should log it, unless the reply code is `530` (```denied`'').

  [`log_if_not_unavail`] If true, then when the reply to the current request comes in, Bro should log it, unless the reply code is `550` (```unavail`'').

  [`log_it`] If true, then when the reply to the current request comes in, Bro should log it.

##
`ftp` variables

The standard script defines the following redefinable variables:

  [``ftp_guest_ids : set[string]``] A set of usernames associated with publicly accessible ``guest'' services. Bro interprets guest usernames as indicating Bro should use the authentication password as the effective username.

  Default: `{ "anonymous", "ftp", "guest", }`.

  [``ftp_skip_hot : set[addr, addr, string]``] Entries indicate that a connection from the first given address to the second given address, using the given string username, should not be treated as hot even if the username is sensitive.

  Default: empty.

  Example: redefining `ftp_skip_hot` using

      redef ftp_skip_hot: set[addr, addr, string] += {
          [[bob1.dsl.home.net, bob2.dsl.home.net], bob.work.com, "root"],
      };

  would result in Bro not alerting on FTP connections as user `"root"` from either `bob1.dsl.home.net` or `bob2.dsl.home.net` to the server running on `bob.work.com`.

  [``ftp_hot_files : pattern``] Bro matches the argument given in each FTP file manipulation request (RETR, STOR, etc.) against this pattern to see if the file is sensitive. If so, and if the request succeeds, then the access is logged.

  `eggdrop` Default: a pattern that matches various flavors of password files, plus any string with `eggdrop` in it. Note: Eggdrop is an IRC management tool often installed by certain attackers upon a successful break-in.

  [``ftp_not_actually_hot_files : pattern``] A pattern giving exceptions to `ftp_hot_files`. It turns out that a pattern like `/passwd/` generates a lot of false hits, such as from `passwd.c` (source for the passwd utility; this can turn up in FTP sessions that fetch entire sets of utility sources using `MGET`) or `passwd.html` (a Web page explaining how to enter a password for accessing a particular page).

  Default: `/(passwd|shadow).*`\.`(c|gif|htm|pl|rpm|tar|zip)/` .

  [``ftp_hot_guest_files : pattern``] Files that guests should not attempt to access.

  Default: `.rhosts` and `.forward` .

  [``skip_unexpected : set[addr]``] If a new host (address) unexpectedly connects to the endpoint specified in a `PORT` or `PASV` directive, then if either the original host or the new host is in this set, no message is generated. The idea is that you can specify multi-homed hosts that frequently show up in your FTP traffic, as these can generate innocuous warnings about connections from unexpected hosts.

  Default: some `hp.com` hosts, as an example. Most are specified as raw IP addresses rather than hostnames, since the hostnames don't always consistently resolve.

  [``skip_unexpected_net : set[addr]``] The same as `skip_unexpected`, except addresses are masked to /24 and /16 before looked up in this set.

  Default: empty.

Figure 7.7: Example of FTP log file entries for a single FTP session.

In addition, `ftp_log` holds the name of the FTP log file to which Bro writes FTP session summaries. It defaults to `open_log_file("ftp")`.

Figure 7.16.2 shows an example of what entries in this file look like. Here we see a transcript of the 26th FTP session seen since Bro started running. The first line gives its start time and the participating hosts and ports. The next line (split across two lines above for clarity) gives the server's welcome banner. The client then logged in as user ```anonymous`'', and because this is one of the guest usernames, Bro recorded their password too, which in this case was ```IEUser@`'' (a useless string supplied by their Web browser). The server accepted this authentication, so the status on the line is ```(logged in)`''.

The client then issues a request for the Image file type, to which the server agreed. Next they issued a `PASV` directive, and received a response instructing them to connect to the server on port `2427/tcp` for the next transfer. At this point, after issuing a `SIZE` directive (to which the server returned 1,675,597 bytes), they send `RETR` to fetch the file /pub/OB/4.0/JOB-4.0.3.zip. However, before the transfer completed, they issued `ABOR`, but the transfer finished before the server processed the abort, so the log shows a status of `(completed)`. Furthermore, because the client issued two commands without waiting for an intervening response, these are shown together in the log file, and the line marked with a ```*`'' so it draws the eye. Finally, because Bro paired up the `(completed)` with the multi-request line, it then treats the response to the `ABOR` command as a reply by itself, showing in the last line that the server reported it successfully carried out the abort.

The corresponding lines in the `red` file look like:

        972499885.784104 565.836 ftp 118 427 131.243.70.68 64.55.26.206
            RSTO L #26 anonymous/IEUser@
        972499888.984116 165.098 ftp-data ? 1675597 131.243.70.68 64.55.26.206
            RSTO L

The first line summarizes the FTP control session (over which the client sends its requests and receives the server's responses). It includes an `addl` annotation of ```#26 anonymous/IEUser@`'', summarizing the session number (so you can find the corresponding records in the `ftp` log file) and the authentication information.

The second line summarizes the single FTP data transfer, of 1,675,597 bytes. The amount of data sent by the client for this connection is shown as unknown because the client aborted the connection with a RST (hence the state `RSTO`). For connections that Bro does not look inside (such as FTP data transfers), it learns the amount of data transferred from the sequence numbers of the SYN and FIN connection control packets, and can't (reliably) learn them for the sender of a RST. (It can for the receiver of the RST.)

They also aborted the control session (again, state `RSTO`), but in this case, Bro captured all of the packets of the session, so it could still assign sizes to both directions.

##
`ftp` functions

The standard `ftp` script provides one function for external use:

  [``is_ftp_data_conn`(c: connection): bool``` ] Returns true if the given connection matches one we're expecting as the data connection half of an FTP session. Note: This function is not idempotent: if the connection matches an expected one, then Bro updates its state such that that connection is no longer expected. It also logs a discrepancy if the connection appears to be usurping another one that generated either a ```PORT`'' or a ```PASV`'' directive.

  Also returns true if the source port is `20/tcp` and there's currently an FTP session active between the originator and responder, in case for some reason Bro's bookkeeping is inconsistent.

##
`ftp` event handlers

The standard script handles the following events:

  [``ftp_request (c: connection, command: string, arg: string)``] Invoked upon the client side of connection `c` having made the request `command` with the argument `arg`.

  The processing depends on the particular command:

  `USER`
    Specifies the username that the client wishes to use for authentication. If it is sensitive--in `hot_ids` (which the `ftp` analyzer accesses via a `@load` of `hot-ids`)--then the analyzer flags the FTP session as log-worthy. In addition, if the username is in `forbidden_ids`, then the analyzer terminates the session.

    The analyzer also updates the connection's `addl` field with the username.

  `PASS`
    Specifies the password to use for authentication.

    If the password is empty and the username appears in `forbidden_ids_if_no_password` (also from the `hot-ids` analyzer), then the analyzer terminates the connection.

    If the username corresponds to a guest account (`ftp_guest_ids`), then the analyzer updates the connection's `addl` field with the password as additional account information. Otherwise, it generates an `account_tried` event to facilitate detection of password guessing.

  `PORT`
    Instructs the FTP server to connect to the given IP address and port for delivery of the next FTP data item. The analyzer first checks the address/port specifier for validity. If valid, it will generate an alert if either the address specified in the directive does not match that of the client, or if the port corresponds to a ``privileged'' port, i.e., one in the range 0-1023. Finally, it establishes state so that `is_ftp_data_conn` can identify a subsequent connection corresponding to this directive as belonging to this FTP session.

  `ACCT`
    Specifies additional accounting information associated with a session, which the analyzer simply adds to the connection's `addl` field.

  `APPE`, `CWD`, `DELE`, `MKD`, `RETR`, `RMD`, `RNFR`, `RNTO`, `STOR`, `STOU`
    All of these manipulate files (and directories). The analyzer checks the filename against the policies to see if it is sensitive in the context of the given username (i.e., guest or non-guest), and, if so, marks the connection to generate an alert unless the operation fails. The analyzer also checks for an excessively long filename, currently by checking its length against a Deficiency: hardwired maximum of 250 bytes.

  [``ftp_reply (c: connection, code: count, msg: string, cont_resp: bool)``] Invoked upon the server side of connection `c` having replied to a request using the given status code and text message. `cont_resp` is true if the reply line is tagged as being continued to the next line. The analyzer only processes requests when the last line of a continued reply is received.

  The analyzer checks the reply against any expected for the connection (for example, ```log_if_not_denied`'') and generates alerts accordingly. If the reply corresponds to a `PASV` directive, then it parses the address/port specification in the reply and generates alerts in an analogous fashion as done by the `ftp_request` handler for `PORT` directives.

  Finally, if the reply is not one that the analyzer is hardwired to skip (code `150`, used at the beginning of a data transfer, and code `331`, used to prompt for a password), then it writes a summary of the request and reply to the FTP log file (§ ). Also, if the reply is an ``orphan'' (there was no corresponding request, perhaps because Bro started up after the request was made), then the reply is summarized in the log file by itself.

The standard `ftp` script defines one other handler, an instance of `connection_finished` used to flush FTP session information in case the session terminates abnormally and no reply is seen to the pending request(s).

#
The `http` Analyzer

The `http` analyzer processes traffic associated with the Hyper Text Transfer Protocol (HTTP) [RFC1945,RFC2616], the main protocol used by the Web. Bro instantiates an `http` analyzer for any connection with service port `80/tcp`, providing you have loaded the `http` analyzer, or defined a handler for `http_request`. It also instantiates an analyzer for service ports `8080/tcp` and `8000/tcp`, as these are often also used for Web servers.

The analyzer uses a capture filter of ```tcp dst port 80 or tcp dst port 8080 or tcp dst port 8000`'' (§ ). Note: This filter excludes traffic sent by an HTTP server (that would be matched by `tcp src port 80`, etc.), because Deficiency: Bro doesn't yet have an analyzer for HTTP replies. It generates summaries of HTTP sessions (connections between the same client and server) and looks for access to sensitive URIs (effectively, URLs).

##
`http` variables

  [``sensitive_URIs : pattern``] Any HTTP method (e.g., `GET`, `HEAD`, `POST`) specifying a URI that matches this pattern is flagged as sensitive.

  Default: URIs with `/etc/passwd` or `/etc/shadow` embedded in them, or `/cfdocs/expeval` (used in some Cold Fusion exploits). Note: This latter generates some false hits; it's mainly included just to convey the notion of looking for direct attacks rather than attacks used to exploit sensitive files like the first ones.

  Deficiency: It would be very handy to have variables providing hooks for more context when considering whether a particular access is sensitive, such as whether the request was inbound or outbound.

  [``sensitive_post_URIs : pattern``] Any `POST` method specifying a URI that matches this pattern is flagged as sensitive.

  Default: URIs with `wwwroot` embedded in them.

Figure 7.8: Example of HTTP log file entries for a single HTTP session.

In addition, `http_log` holds the name of the HTTP log file to which Bro writes HTTP session summaries. It defaults to `open_log_file("http")`.

Figure 7.17.1 shows an example of what entries in this file look like. Here we see a transcript of the 1596th HTTP session seen since Bro started running. The first line gives its start time and the participating hosts. The next five lines all correspond to `GET` methods retrieving different items from the Web server. Deficiency: Bro can't log whether the retrievals succeeded or failed because it doesn't yet have an HTTP reply analyzer.

The corresponding lines in the `red` file look like:

        972482762.872695 481.551 http 441 5040 131.243.2.12 200.241.229.80
            S3 X %10596
        972482764.686470 18.7611 http 596 7712 131.243.2.12 200.241.229.80
            S3 X %10596
        972482764.685047 ? http 603 2959 131.243.2.12 200.241.229.80
            S1 X %10596

That there are three rather than five reflects (i) that the client used persistent HTTP, and so didn't need one connection per item, but also (ii) the client used three parallel connections (the maximum the standard allows is only two) to fetch the items more quickly. As with FTP sessions, the `%10596` `addl` annotation lets you correlate the `red` entries with the `http` log entries.

Note: All three of the connections wound up in unusual states. The first two are in state `S3`, which, as indicated by Table 7.3.6 means that the responder (in this case, the Web server) attempted to close the connection, but their was no reply from the originator. The last is in state `S1`, indicating that neither side attempted to close the connection (which is why no duration is listed for the connection).

##
`http` event handlers

The standard HTTP script defines one event handler:

  [``http_request (c: connection, request: string, URI: string)``] Invoked whenever the client side of the given connection generates an HTTP request. `request` gives the HTTP method and `URI` the associated resource. The analyzer matches the URI against the ones defined as sensitive, as given above.

Deficiency: As mentioned above, the event engine does not currently generate an `http_reply` event. This is for two reasons: first, the HTTP request stream is much lower volume than the HTTP reply stream, and I was interested in the degree to which Bro could get away without analyzing the higher volume stream. (Of course, this argument is shallow, since one could control whether or not Bro should analyze HTTP replies by deciding whether or not to define an `http_reply` handler.) Second, matching HTTP replies in their full generality involves a lot of work, because the HTTP standard allows replies to be delimited in a number of ways. That said, most of the work for implementing `http_reply` is already done in the event engine, but it is missing testing and debugging.

#
The `ident` Analyzer

The `ident` analyzer processes traffic associated with the Identification Protocol [RFC1413], which provides a simple service whereby clients can query Ident servers to discover user information associated with an existing connection between the server's host and the client's host. Bro instantiates an `ident` analyzer for any connection with service port `113/tcp`, providing you have loaded the `ident` analyzer, or defined a handler for `ident_request`, `ident_reply`, or `ident_error`.

The analyzer uses a capture filter of ```tcp port 113`'' (§ ). The `ident_reply` handler annotates the `addl` field of the connection for which the Ident client made its query with the user information returned in the reply. It also checks the user information against sensitive usernames, because a match indicates that the connection in the Ident query was initiated by a possibly-compromised account.

##
`ident` variables

The standard script defines the following pair of redefinable variables:

  [``hot_ident_ids : set[string]``] usernames to flag as sensitive if they appear in an Ident reply.

  Default: `always_hot_ids` (§ ).

  [``hot_ident_exceptions : set[string]``] usernames not to consider sensitive even if they appear in `hot_ident_ids`.

  Default: `{ "uucp", "nuucp", "daemon", }`. These usernames are exceptions because daemons sometimes run with the given user ids and their use is often innocuous.

##
`ident` event handlers

The standard script handles the following events:

  [``ident_request (c: connection, lport: port, rport: port)``] Invoked when a client request arrives on connection `c`, querying about the connection from local port `lport` to remote port `rport`, where local and remote are relative to the client.

  [``ident_reply (c: connection, lport: port, rport: port, user_id: string, system: string)``] Invoked when a server replies to an Ident request. `lport` and `rport` are again the local and remote ports (relative to the client) of the connection being asked about. `user_id` is the user information returned in the Ident server's reply, and `system` is information regarding the operating system (the Ident specification [RFC1413] does not further standardize this information).

  The handler annotates the queried connection with the user information, which it also checks against `hot_ident_ids` and `hot_ident_exceptions` as discussed above. At present, it does nothing with the `system` information.

  [``ident_error (c: connection, lport: port, rport: port, line: string)``] Invoked when the given request yielded an error reply from the Ident server. The handler annotates the connection with `ident/``<`error`>`, where error is the text given in `line`.

#
The `login` Analyzer

The `login` analyzer inspects interactive login sessions to extract username and password information, and monitors user keystrokes and the text returned by the login server. It is one of the most powerful Bro modules for detecting break-ins to Unix systems because of the ability to look for particular commands that attackers often execute once they have penetrated a Unix machine.

The analyzer is generic in the sense that it applies to more than one protocol. Currently, Bro instantiates a `login` analyzer for both Telnet [RFC854] and Rlogin [RFC1282] traffic. In principle, it could do the same for other protocols such as SSH [YKSRL00] or perhaps X11 [RFC1013], if one could write the corresponding elements of the event engine to decrypt the SSH session (naturally, this would require access to the encryption keys) or extract authentication information and keystrokes from the X11 event stream. Note: The analyzer does an exceedingly limited form of SSH analysis; see `hot_ssh_orig_ports`.

For Telnet, the event engine knows how to remove in-band Telnet option sequences [RFC855] from the text stream, and does not deliver these to the event handlers, except for a few options that the engine analyzes in detail (such as attempts to negotiate authentication). Unfortunately, the Telnet protocol does not include any explicit marking of username or password information (unlike the FTP protocol, as discussed in § ). Consequently, Bro employs a series of heuristics that attempt to extract the username and password from the authentication dialog the session is presumed to begin with. The analysis becomes quite complicated due to the possible use of type-ahead and editing sequences by the user, plus the possibility that the user may be an attacker who attempts to mislead the heuristics in order to disguise the username they are accessing.

Analyzing Rlogin is nominally easier than analyzing Telnet because Rlogin has a simpler in-band option scheme, and because the Rlogin protocol explicitly indicates the username in the initial connection dialog. However, this last is not actually a help to the analyzer, because for most Rlogin servers, if the initial username fails authentication (for example, is not present in the `.rhosts` file local to the server), then the server falls back on the same authentication dialog as with Telnet (prompting for username and then password, or perhaps just for a password to go with the transmitted username). Consequently, the event engine employs the same set of heuristics as for Telnet.

Each connection processed by the analyzer is in a distinct state: user attempting to authenticate, user has successfully authenticated, analyzer is skipping any further processing, or the analyzer is confused (§ ). You can find out the state of a given connection using `get_login_state`.

The analyzer uses a capture filter of ```tcp port 23 or tcp port 513`'' (§ ). It annotates each connection with the username(s) present in the authentication dialog. If the username was authenticated successfully, then it encloses the annotation in quotes. If the authentication failed, then the name is marked as `failed/``<`username`>`. So, for example, if user ``smith'' successfully authenticates, then the connection's `addl` field will have `"smith"` appended to it:

    931803523.006848 254.377 telnet 324 8891 1.2.3.4 5.6.7.8 SF L "smith"

while if ``smith'' failed to authenticate, the report will look like:

    931803523.006848 254.377 telnet 324 8891 1.2.3.4 5.6.7.8 SF L fail/smith

and if they first tried as ``smith'' and failed, and then succeeded as ``jones'', the record would look like:

    931803523.006848 254.377 telnet 324 8891 1.2.3.4 5.6.7.8 SF L fail/smith "jones"

Note: The event engine's heuristics can sometimes get out of synch such that it interprets a password as a username; in addition, users sometimes type their password when they should instead enter their username. Consequently, the connection logs sometimes include passwords in the annotations, and so should be treated as very sensitive information (e.g., not readable by any user other than the one running Bro).

##
`login` analyzer confusion

Because there is no well-defined protocol for Telnet authentication (or Rlogin, if the initial `.rhosts` authentication fails), the `login` analyzer employs a set of heuristics to detect the username, password, and whether the authentication attempt succeeded. All in all, these heuristics work quite well, but it is possible for them to become confused and reach incorrect conclusions.

Table 7.4: Different types of confusion that `login` analyzer can report.
Type of confusion | Meaning
`"excessive_typeahead"` | The user has typed ahead 12 or more lines. Deficiency: The upper bound should be adjustable.
`"extra_repeat_text"` | The user has entered more than one VMS repeat sequence (an escape followed by ```[A`'') on the same line. Note: Bro determines that a login session involves a VMS server if the server prompts with ```"Username:"`''. It then interprets VMS repeat sequences as indicating it should replace the current line with the previous line.
`"multiple_USERs"` | The user has specified more than one username using the `$USER` environment variable.
`"multiple_login_prompts"` | The analyzer has seen several login prompts on the same line, and has not seen a corresponding number of lines typed ahead previously by the user.
`"no_login_prompt"` | The analyzer has seen 50 lines sent by the server without any of them matching `login_prompts`. Deficiency: The value of 50 should be adjustable.
`"no_username"` | The analyzer is generating an event after having already seen a login failure, but the user's input has not provided another username to include with the event. Note: If the analyzer's heuristics indicate it's okay that no new username has been given, such as when the event is generated due to one connection endpoint closing the connection, then it instead uses the username `<none>` .
`"no_username2"` | The analyzer saw an additional password prompt without seeing an intervening username, and it has no previous username to reuse.
`"non_empty_multi_login"` | The analyzer saw multiple adjacent login prompts, with an apparently ignored intervening username typed-ahead between them.
`"possible_login_ploy"` | The client sent text that matches one of the patterns reflecting text usually sent by the server. This form of confusion can reflect an attacker attempting to evade the monitor. For example, the client may have sent the text ```login:`'' as a username so that when echoed back by the server, the analyzer would misinterpret it as reflecting another login prompt from the server.
`"repeat_without_username"` | The user entered a VMS repeat sequence but there is no username to repeat. (See `extra_repeat_text` for a discussion of the analyzer's heuristics for dealing with VMS servers.)
`"responder_environment"` | The responder (login server) has signaled a set of environment variables to the originator (login client). This is in the opposite direction as to what makes sense.
`"username_with_embedded_repeat"` | The line repeated by a VMS server in response to a repeat sequence itself contains a repeat sequence.

Bro attempts to detect such confusion. If it does, then it generates a `login_confused` event, after which the event engine will no longer attempt to follow the authentication dialog. In particular, it will not generate subsequent `login_failure` or `login_success` events. The `login_confused` event includes a string describing the type of confusion, using one of the values given in Table 7.19.1.

##
`login` variables

The standard script defines a large number of variables for refining the analysis policy:

  [``input_trouble : pattern``] lists patterns that the analyzer should flag if they appear in the user's input (keystroke) stream.

  The analyzer searches for these patterns both in the raw text typed by the user and the same lines after applying editing using the `edit` function twice: once with interpreting BS (ctrl-H) as delete-one-character, and once with DEL as the edit character. If any of these matches, then the analyzer considers the pattern to have matched.

  `eggdrop` Default: a pattern matching occurrences of the strings ```rewt`'', ```eggdrop`'', ```loadmodule`'', or ```/bin/eject`''. The first of these is a popular username attackers use for root backdoor accounts. The second reflects that one prevalent class of attackers are devotees of Internet Relay Chat (IRC), who frequently upon breaking into an account install the IRC `eggdrop` utility.

  [``edited_input_trouble : pattern``] is the same as `input_trouble` except the analyzer only checks the edited user input against the pattern, not the raw input (see above).

  This variable is provided so you can specify patterns that can occur innocuously as typos; whenever the user corrects the typo before terminating the line, the pattern won't match, because it won't be present in the edited version of the line. In addition, for matches to these patterns, the analyzer delays reporting the match until it sees the next line of output from the server. It then includes both the line that triggered the match and the corresponding response from the server, which makes it easy for a human inspecting the logs to tell if the occurrence of the pattern was in fact innocuous.

  Here's an example of an innocuous report:

      936723303.760483 1.2.3.4/21550 > 5.6.7.8/telnet
          input "cd ..." yielded output "ksh: ...:  not found."

  It was flagged because the user's input included ```...`'', a name commonly used by attackers to surreptitiously hide a directory containing their tools and the like. However, we see from the Telnet server's response that this was not actual access to such a directory, but merely a typing mistake.

  On the other hand:

      937528764.579039 1.2.3.4/3834 > 5.6.7.8/telnet
          input "cd ..." yielded output "maroon# ftp sunspot.sunspot.noao.edu "

  shows a problem--the lines returned by the server was a root prompt (```maroon`#``''), to which the user issued a command to access a remote FTP server.

  Deficiency: The analyzer should decouple the notion of waiting to receive the server's reply from the notion of matching only the edited form of the line; there might be raw inputs for which it is useful to see the server's response, and edited inputs for which the server's response is unimportant in terms of knowing that the input spells trouble.

  Default: the pattern

          /[ \t]*cd[ \t]+((['"]?\.\.\.)|(["'](\.[^"']*)[ \t]))/

  which looks for a ```cd`'' command to either a directory beginning with ```...`'' (optionally quoted by the user) or a directory name beginning with ```.`'' that is quoted and includes an embedded blank or tab.

  [``output_trouble : pattern``] lists patterns that the analyzer should flag if they occur in the output sent by the login server back to the user.

  `PATH_UTMP` `smashdu.c` Default: the pattern

            /^-r.s.*root.*\/bin\/(sh|csh|tcsh)/
          | /Jumping to address/
          | /smashdu\.c/
          | /PATH_UTMP/
          | /Log started at =/
          | /www\.anticode\.com/
          | /smurf\.c by TFreak/
          | /Trojaning in progress/
          | /Super Linux Xploit/

  The first of these triggers any time the user inspects with the ls utility an executable whose pathname ends in `/bin/` followed by one of the popular command shells, and the ls output shows that the command shell has been altered to be setuid to root. The remainder match either the output generated by some popular exploit tools (for example, ```Jumping to address`'', present in many buffer overflow exploit tools), exploit tool names (```smashdu.c`''), text found within the tool source code (```smurf.c by TFreak`''), or URLs accessed (say via the lynx or fetch utilities) to retrieve attack software (```www.anticode.com`'').

  [``backdoor_prompts : pattern``] lists patterns that the analyzer should flag if they are seen as the first line sent by the server to the user, because they often correspond with backdoors that offer a remote user immediate command shell access without having to first authenticate.

  Default: the pattern ```/^[!-~]*( ?)[#%$] /`'', which matches a line that begins with a series of printable, non-blank characters and ends with a likely prompt character, with a blank just after the prompt character and perhaps before it.

  [``non_backdoor_prompts : pattern``] lists patterns that if a possible backdoor prompt also matches, then the analyzer should not consider the server output as indicating a backdoor prompt. Used to limit false positives for `backdoor_prompts`.

  Default: the pattern ```/^ *#.*#/`'', which catches lines with more than one occurrence of a `#`. Some servers generate such lines as part of their welcome banner.

  [``hot_terminal_types : pattern``] lists ``magic'' terminal types sometimes used by attackers to access backdoors. Both Telnet and Rlogin have mechanisms for negotiating a terminal type (name; e.g., ```xterm`''); these backdoors trigger and skip authentication if the name has a particular value.

  `VT666` Default: the name ```VT666`'', one of the trigger terminal types we've observed in practice.

  [``hot_telnet_orig_ports : set[port]``] Some Telnet backdoors trigger if the ephemeral port used by the client side of the connection happens to be a particular value. This variable is used to list the port values whose use should be considered as possibly indicating a backdoor. Note: Clearly, this mechanism can generate false positives when the client by chance happens to choose one of the listed ports.

  Default: `53982/tcp`, one of the trigger ports we have observed in practice.

  Deficiency: There should be a corresponding variable for Rlogin backdoors triggered by a similar mechanism.

  [``hot_ssh_orig_ports : set[port]``] Similar to `hot_telnet_orig_ports`, only for SSH.

  Default: `31337/tcp`, a trigger port that we've observed in practice.

  [``skip_authentication : set[string]``] A set of strings that, if present in the server's initial output (i.e., its welcome banner), indicates the analyzer should not attempt to analyze the session for an authentication dialog. This is used for servers that provide public access and don't bother authenticating the user.

  Default: the string `"WELCOME TO THE BERKELEY PUBLIC LIBRARY"`, which corresponds to a frequently accessed public server in the Berkeley area. (Obviously, we include this default as an example, and not because it will be appropriate for most Bro users! But it does little harm to include it.)

  Deficiency: It would be more natural if this variable and a number of others listed below were of type `pattern` rather than `set[string]`. They are actually converted internally by the event engine into regular expressions.

  [``direct_login_prompts : set[string]``] A set of strings that if seen during the authentication dialog mean that the user will be logged in as soon as they answer the prompt.

  Default: `"TERMINAL?"`, a prompt used by some terminal servers.

  [``login_prompts : set[string]``] A set of strings corresponding to login username prompts during an authentication dialog.

  Default: the strings

          Login:
          login:
          Name:
          Username:
          User:
          Member Name

  and the default contents of `direct_login_prompts`.

  [``login_failure_msgs : set[string]``] A set of strings that if seen in text sent by the server during the authentication dialog correspond to a failed login attempt.

  Default: the strings

          invalid
          Invalid
          incorrect
          Incorrect
          failure
          Failure,
          User authorization failure,
          Login failed,
          INVALID
          Sorry,
          Sorry.

  [``login_non_failure_msgs : set[string]``] A set of strings similar to `login_failure_msgs` that if present mean that the server text does not actually correspond to an authentication failure (i.e., if `login_failure_msgs` also matches, it's a false positive).

  Default: the strings

          Failures
          failures
          failure since last successful login
          failures since last successful login

  [``router_prompts : set[string]``] A set of strings corresponding to prompts returned by the local routers when a user successfully authenticates to the router. For the purpose of this variable, see the next variable.

  Default: empty.

  [``login_success_msgs : set[string]``] A set of strings that if seen in text sent by the server during the authentication dialog correspond to a successful authentication attempt.

  Default: the strings

          Last login
          Last successful login
          Last   successful login
          checking for disk quotas
          unsuccessful login attempts
          failure since last successful login
          failures since last successful login

  and the default contents of the `router_prompts` variable.

  Deficiency: Since by default `router_prompts` is empty, this last inclusion does nothing. In particular, if you redefine `router_prompts` then `login_success_msgs` will not pick up the change; you will need to redefine it to (again) include `router_prompts`, using: `redef login_success_msgs += router_prompts`. This is clearly a misfeature of Bro and will be fixed one fine day.

  [``login_timeouts : set[string]``] A set of strings that if seen in text sent by the server during the authentication dialog correspond to the server having timed out the authentication attempt.

  Default: the strings

          timeout
          timed out
          Timeout
          Timed out
          Error reading command input

  (This last is returned by the VMS operating system.)

  [``non_ASCII_hosts : set[addr]``] A set of addresses corresponding to hosts whose login servers do not (primarily) use 7-bit ASCII. The analyzer will not attempt to analyze authentication dialogs to such hosts, and will not complain about huge lines generated by either the sender or receiver (per `excessive_line`).

  Default: empty.

  [``skip_logins_to : set[addr]``] A set of addresses corresponding to hosts for which the analyzer should not attempt to analyze authentication dialogs.

  Default: the (empty) contents of `non_ASCII_hosts`.

  [``always_hot_login_ids : set[string]``] A set of usernames that the analyzer should always flag as sensitive, even if they're seen in a session for which the analyzer is confused (§ ).

  Default: the value of `always_hot_ids` defined by the `hot` analyzer.

  [``hot_login_ids : set[string]``] A set of usernames that the analyzer should flag as sensitive, unless it sees them in a session for which the analyzer is confused (§ ).

  Default: the value of `hot_ids` defined by the `hot-ids` analyzer.

  [``rlogin_id_okay_if_no_password_exposed : set[string]``] A set of username exceptions to `hot_login_ids` which the analyzer should not flag as sensitive if the user authenticated without exposing a password (so, for example, via `.rhosts`).

  Default: the username `"root"`.

##
`login` functions

The standard `login` script provides the following functions for external use:

  [``is_login_conn`(c: connection): bool``` ] Returns true if the given connection is one analyzed by `login` (currently, Telnet or Rlogin), false otherwise.

  [``hot_login`(c: connection, msg: string, tag: string)``` ] Marks the given connection as hot, logs the given message, and demultiplexes (§ ) the subsequent server-side contents of the connection to a filename based on `tag` and the client-side to a filename based on the name `"keys"`. No return value.

  [``is_hot_id`(id: string, successful: bool, confused: bool): bool``` ] Returns true if the username id should be considered sensitive, given that the user either did or did not successfully authenticate, and that the analyze was or was not in a confused state (§ ).

  [``is_forbidden_id`(id: string): bool``` ] Returns true if the username id is present in `forbidden_ids` or `forbidden_id_patterns`.

  [``edit_and_check_line`(c: connection, line: string, successful: bool): check_info``` ] Tests whether the given line of text seen on connection `c` includes a sensitive username, after first applying BS and DEL keystroke editing (§ ). `successful` should be true if the user has successfully authenticated, false otherwise.

  The return value is a `check_info` record, which contains four `check_info` fields:

    [`expanded_line`] All of the different editing interpretations of the line, separated by commas. For example, if the original line is

    > `"`rob<`DEL`><`BS`><`BS`>ot`"`

    then the different editing interpretations are `"`ro<`BS`><`BS`>ot`"` and `"root"`, so the return value will be:

    > `"`rob<`DEL`><`BS`><`BS`>ot`,`ro<`BS`><`BS`>ot`,root"`

    Deficiency: Ideally, these values would be returned in a list of some form, so that they can be accessed separately and unambiguously. The current form is really suitable only for display to a person, and even that can be quite confusing if `line` happens to contain commas already. Or, perhaps an algorithm of ``simply pick the shortest'' would find the correct editing every time anyway.

  `hot: bool`
    True if any editing sequence resulted in a match against a sensitive username.

  `hot_id: string`
    The version of the input line (with or without editing) that was considered hot, or an empty string if none.

  `forbidden: bool`
    True if any editing sequence resulted in a match against a username considered ``forbidden'', per `is_forbidden_id`.

  [``edit_and_check_user`(c: connection, user: string, successful: bool, fmt_s: string): bool``` ] Tests whether the given username used for authentication on connection `c` is sensitive, after first applying BS and DEL keystroke editing (§ ). `successful` should be true if the user has successfully authenticated, false otherwise.

  `fmt_s` is a `fmt` format specifying how the username information should be included in the connection's `addl` field. It takes two `string` parameters, the current value of the field and the expanded version of the username as described in `expanded_line`.

  If `edit_and_check_line` indicates that the username is sensitive, then `edit_and_check_user` records the connection into its own demultiplexing files (§ ). If the username is forbidden, then unless the analyzer is confused, we attempt to terminate the connection using `terminate_connection`.

  Returns true if the connection is now considered ``hot,'' either due to having a sensitive username, or because it was hot upon entry to the function.

  [``edit_and_check_password`(c: connection, password: string): bool``` ] Checks the given password to see whether it contains a sensitive username. If so, then marks the connection as hot and logs the sensitive password. No return value.

  Note: The purpose of this function is to catch instances in which the event engine becomes out of synch with the authentication dialog and mistakes what is, in fact, a username being entered, for a password being entered. Such confusion can come about either due to a failure of the event engine's heuristics, or due to deliberate manipulation of the event engine by an attacker.

##
`login` event handlers

The standard `login` script handles the following events:

  [``login_failure (c: connection, user: string, client_user: string, password: string, line: string)``] Invoked when the event engine has seen a failed attempt to authenticate as `user` with `password` on the given connection `c`. `client_user` is the user's username on the client side of the connection. For Telnet connections, this is an empty string, but for Rlogin connections, it is the client name passed in the initial authentication information (to check against `.rhosts`). `line` is the line of text that led the analyzer to conclude that the authentication had failed.

  The analyzer first generates an `account_tried` event to facilitate detection of password guessing, and then checks for a sensitive username or password. If the username was not sensitive and the password is empty, then no further analysis is applied, since clearly the attempt was half-hearted and aborted. Otherwise, the analyzer annotates the connection's `addl` field with `fail/`<`username`>`` to mark the authentication failure, and also checks the `client_user` to see if it is sensitive. If we then find that the connection is hot, the analyzer logs a message to that effect.

  [``login_success (c: connection, user: string, client_user: string, password: string, line: string)``] Invoked when the event engine has seen a successful attempt to authenticate. The parameters are the same as for `login_failure`.

  The analyzer invokes `check_hot` with mode `APPL_ESTABLISHED` since the application session has now been established. It generates an `account_tried` event to facilitate detection of password guessing, and then checks for a sensitive username or password. The event engine uses the special password `"`<`none`>`"` to indicate that no password was exposed, and this mitigates the sensitivity of logins using particular usernames per `rlogin_id_okay_if_no_password_exposed`.

  The analyzer annotates the connection's `addl` field with `"`<`username`>`"` to mark the successful authentication. Finally, if we then find that the connection is hot, the analyzer logs a message to that effect.

  [``login_input_line (c: connection, line: string)``] Invoked for every line of text sent by the client side of the login session to the server side. The analyzer matches the text against `input_trouble` and `edited_input_trouble` and invokes `hot_login` with a tag of `"trb"` if it sees a match, which will log an alert concerning the connection. However, this invocation is only done while the connection's `hot` field count is , to avoid cascaded alerts when an attacker gets really busy and steps on a lot of sensitive patterns.

  [``login_output_line (c: connection, line: string)``] Invoked for every line of text sent by the server side of the login session to the client side. The analyzer checks `backdoor_prompts` and any pending input alerts that were waiting on the server output, per `edited_input_trouble`. These last are then logged unless the output matched the pattern:

          /No such file or directory/

  Deficiency: Clearly, this pattern should not be hardwired but instead specified by a redefinable variable.

  Finally, if the line is not too long and the text matches `output_trouble` and the connection's `hot` field count is (to avoid cascaded alerts), the analyzer invokes `hot_login` with a tag of `"trb"`. Deficiency: ``Too long'' is hardwired to be a length bytes. It, too, should be specifiable via a redefinable variable. Note: We might wonder if not checking overly long lines presents an evasion threat: the attacker can bury their access to a sensitive string in an excessive line and thus avoid detection. While this is true, it doesn't appear to cost much. First, some of the sensitive patterns are generated in server output that will be hard to manipulate into being overly long. Second, if the attacker is trying to avoid detection, there are easier ways, such as passing their output through a filter that alters it a good deal.

  [``login_confused (c: connection, msg: string, line: string)``] Invoked when the event engine's heuristics have concluded that they have become confused and can no longer correctly track the authentication dialog (§ ). `msg` gives the particular problem the heuristics detected (for example, `multiple_login_prompts` means that the engine saw several login prompts in a row, without the type-ahead from the client side presumed necessary to cause them) and `line` the line of text that caused the heuristics to conclude they were confused.

  Once declaring that it's confused, the event engine will no longer attempt to follow the authentication dialog. In particular, it will not generate subsequent `login_failure` or `login_success` events.

  Upon this event, the standard `login` script invokes `check_hot` with mode `APPL_ESTABLISHED` since it could well be that the application session is now established (it can't know for sure, of course, because the event engine has given up). It annotates the connection's `addl` field with `confused/``<`line`>` to mark the confused state, and then logs to the `weird` file the particulars of the connection and the type of confusion (`msg`). Deficiency: This should be done by generating a weird-related event instead.

  Finally, the analyzer invokes `set_record_packets` to specify that all of the packets associated with this connection should be recorded to the `trace` file. Note: For the current `login` analyzer, this call is not needed--it records every packet of every login session anyway, because the generally philosophy is that Bro should record whatever it analyzes, so that the analysis may be repeated or examined in detail. Since the current analyzer looks at every input and output line via `login_input` and `login_output`, it records all of the packets of every such analyzed session. There is commented-out text in `login_success` to be used if `login_input` and `login_output` are not being used; it turns off recording of a session's packets after the user has successfully logged in (assuming the connection is not considered hot).

  [``login_confused_text (c: connection, line: string)``] Invoked for every line the user types after the event engine has entered the confused state. If the connection is not already considered hot, then the analyzer checks for the presence of sensitive usernames in the line using `edit_and_check_line`, and, if present, annotates the connection's `addl` field with `confused/``<`line`>`, logs that the connection has become hot, and invokes `set_record_packets` to record to the `trace` file all of the packets associated with the connection.

  [``login_terminal (c: connection, terminal: string)``] Invoked when the client transmits a terminal type to the server. The mechanism by which the client transmits the type depends on the underlying protocol (Rlogin or Telnet).

  The handler checks the terminal type against `hot_terminal_types` and if it finds a match invokes `hot_login` with a tag of `"trb"`.

  [``excessive_line (c: connection)``] Invoked when the event engine observes a very long line sent by either the client or the server. Such long lines are seen as potential attempts by an attacker to evade the `login` analyzer; or, possibly, as a Login session carrying an unusual application. Note: One example we have observed occurs when a high-bandwidth binary payload protocol such as Napster is sent over the Telnet or Rlogin well-known port in an attempt to either evade detection or tunnel through a firewall.

  This event is actually generic to any TCP connection carrying an application that uses the ``Network Virtual Terminal'' (NVT) abstraction, which presently comprises Telnet and FTP. But the only handler defined in the demonstration Bro policy is for Telnet, hence we discuss it here. For this reason, the handler first invokes `is_login_conn` to check whether the connection is in fact a login session. If so, then if the connection is not hot, and if the analyzer finds the server listed in `non_ASCII_hosts`, then it presumes the long line is due to use of a non-ASCII character set; the analyzer invokes `set_login_state` and `set_record_packets` to avoid further analysis or recording of the connection.

  Otherwise, if the connection is still in the authentication dialog, then the handler generates a `login_confused` event with a confusion-type of `"excessive_line"`, and changes the connection's state to confused.

  Deficiency: The event engine is currently hardwired to consider a line of bytes as ``excessive''; clearly this should be user-redefinable.

  [``inconsistent_option (c: connection)``] NVT options are specified by the client and server stating which options they are willing to support vs. which not, and then instructing one another which in fact they should or should not use for the current connection. If the event engine sees a peer violate either what the other peer has instructed it to do, or what it itself offered in terms of options in the past, then the engine generates an `inconsistent_option` event.

  The handler for this event simply records an entry about it to the `weird` file. Deficiency: The event handler invocation does not include enough information to determine what option was inconsistently specified; in addition, it would be convenient to integrate the handling of problems like this within the general ``weird'' framework.

  Note: As for `excessive_line` above, this event is actually a generic one applicable to any NVT-based protocol. It is handled here because the problem most often crops up for Telnet sessions. Note: Also, the handler does not check to see whether the connection is a login session (as it does for `excessive_line`); it serves as the handler for any NVT session with an excessive line.

  Note: Finally, note that this event can be generated if the session contains a stream of binary data. One way this can occur is when the session is encrypted but Bro fails to recognize this fact.

  [``bad_option (c: connection)``] If an NVT option is either ill-formed (e.g., a bad length field) or unrecognized, then the analyzer generates this event.

  The processing of this event (recording information to the `weird` file) and the various notes and deficiencies associated with it are the same as those for `inconsistent_option` above.

  [``bad_option_termination (c: connection)``] If an NVT option fails to be terminated correctly (for example, a character is seen within the option that is disallowed for use in the option), then the analyzer generates this event.

  The processing of this event (recording information to the `weird` file) and the various notes and deficiencies associated with it are the same as those for `inconsistent_option` above.

  [``authentication_accepted (name: string, c: connection)``] The NVT framework includes options for negotiating authentication. When such an option is sent from client to server and the server replies that it accepts the authentication, then the event engine generates this event.

  The handler annotates the connection's `addl` field with `auth/``<`name`>`, unless that annotation is already present.

  [``authentication_rejected (name: string, c: connection)``] The same as `authentication_accepted`, except invoked when the server replies that it rejects the attempted authentication.

  The handler annotates the connection's `addl` field with `auth-failed/``<`name`>`.

  [``authentication_skipped (c: connection)``] Invoked when the event engine sees a line in the authentication dialog that matches `skip_authentication`.

  The handler annotates the connection's `addl` field with ```(skipped)`'' to mark that authentication was skipped, and then invokes `skip_further_processing` and (unless the connection is hot) `set_record_packets` to skip any further analysis of the connection, and to stop recording its packets to the `trace` file.

``connection_established (c: connection)``
  `connection_established` is a generic event generated for all TCP connections; however, the `login` analyzer defines an additional handler for it.

  The handler first checks (via `is_login_conn`) whether this is a Telnet or Rlogin connection. If so, it generates an `authentication_skipped` event if the server's address occurs in `skip_logins_to`, and also (for Telnet) checks whether the client's port occurs in `hot_telnet_orig_ports`, invoking `hot_login` with the tag `"orig"` if it does.

  For SSH connections, it likewise checks the client's port, but in `hot_ssh_orig_ports`, marking the connection as hot and logging a real-time alert if it is.

``partial_connection (c: connection)``
  As noted earlier, `partial_connection` is a generic event generated for all TCP connections. The `login` analyzer also defines a handler for it, one which (if it's a Telnet/Rlogin connection) sets the connection's state to confused and checks for `hot_telnet_orig_ports`.

  [``activating_encryption (c: connection)``] The NVT framework includes options for negotiating encryption. When such a series of options is successfully negotiated, the event engine generates this event. Note: The negotiation sequence is complex and can fail at a number of points. The event engine does not attempt to generate events for each possible failure, but instead only looks for the option sent after a successful negotiation sequence.

  The handler annotates the connection's `addl` field with ```(encrypted)`'' to mark that authentication was encrypted. Note: The event engine itself marks the connection as requiring no further processing. This is done by the event engine rather than the handler because the event engine cannot do its job (regardless of the policy the handler might desire) in the face of encryption.

#
The `portmapper` Analyzer

The `portmapper` analyzer monitors one particularly important form of remote procedure call (RPC) [RFC1831,RFC1832] traffic: the portmapper service, used to map between RPC program (and version) numbers and the TCP or UDP port on which the service runs for a particular host. For example, rstatd is an RPC service that provides ``remote host status monitoring'' so that a set of hosts can be informed when any of them reboots. rstatd has been assigned a standard RPC program number of 100002. To find out the corresponding TCP or UDP port on a given host, a remote host would usually first contact the portmapper RPC service running on the host and request the port corresponding to program 100002.

Table 7.5: Types of calls to the RPC portmapper service.
Call | Meaning
NULL | A do-nothing call typically provided by all RPC services.
GETPORT | Look up the port associated with a given RPC program.
SET | Add a new port mapping (or replace an existing mapping) for an RPC program.
UNSET | Remove a port mapping.
DUMP | Retrieve all of the RPC program mappings.
CALLIT | Both look up a program and then directly call it.

All in all, clients can make six different types of calls to the portmapper, as summarized in Table 7.20. Attackers often use GETPORT and DUMP to see whether a host may be running an RPC service vulnerable to a known exploit.

The analyzer uses a capture filter of ```port 111`'' (§ ), equivalent to ```tcp port 111 or udp port 111`'' (since the portmapper service ordinarily accepts calls using either TCP or UDP, both on port 111). It checks the different types of portmapper calls against policies expressed using a number of different variables.

Note: An important point not to overlook is that an attacker does not have to first call the portmapper service in order to call an RPC program. They might instead happen to know the port on which the service runs a priori, since for example it may generally run on the same port for a particular operating system; or they might scan the host's different TCP or UDP ports directly looking for a reply from the service. Thus, while portmapper monitoring proves very useful in detecting attacks, it does not provide comprehensive monitoring of attempts to exploit RPC services.

##
`portmapper` variables

The standard script provides the following redefinable variables:

  [``rpc_programs : table[count] of string``] Maps RPC program numbers to a string used to name the service. For example, the `[100002]` entry is mapped to `"rstatd"`.

  Default: a large list of RPC services.

  [``NFS_services : set of string``] Lists the names of those RPC services that correspond to Network File System (NFS) [RFC1094,RFC1813] services. This variable is provided because it is convenient to express policies specific to accessing NFS file systems.

  Default: the services mountd, nfs, pcnfsd, nlockmgr, rquotad, status.

  Deficiency: Bro's notion of NFS is currently confined to just knowledge of the existence of these services. It does not analyze the particulars of different NFS operations.

  [``RPC_okay : set[addr, addr, string]``] Indexed by the host providing a given service and then by the host accessing the service. If an entry is present, it means that the given access is allowed. For example, an entry of:

          [1.2.3.4, 5.6.7.8, "rstatd"]

  means that host `5.6.7.8` is allowed to access the rstatd service on host `1.2.3.4`.

  Default: empty.

  [``RPC_okay_nets : set[net]``] A set of networks allowed to make GETPORT requests without complaint. The notion behind providing this variable is that the listed networks are trusted. However, the trust doesn't extend beyond GETPORT to other portmapper requests, because GETPORT is the only portmapper operation used routinely by a set of hosts trusted by another set of hosts (but that don't belong to the same group, and hence are not issuing SET and UNSET calls).

  Default: empty.

  [``RPC_okay_services : set[string]``] A set of services for which GETPORT requests should not generate complaints. These might be services that are widely invoked and believed exploit-free, such as walld, though care should be taken with blithely assuming that a given service is indeed exploit-free.

  Note that, like for `RPC_okay_nets`, the trust does not extend beyond GETPORT, because it should be the only portmapper operation routinely invoked.

  Default: empty.

  [``NFS_world_servers : set[addr]``] A set of hosts that provide public access to an NFS file system, and thus should not have any of their NFS traffic flagged as possibly sensitive. (The presumption here is that such public servers have been carefully secured against any remote NFS operations.) An example of such a server might be one providing read-only access to a public database.

  Default: empty.

  [``RPC_dump_okay : set[addr, addr]``] Indexed first by the host requesting a portmapper dump, and second by the host from which it's requesting the dump. If an entry is present, then the dump operation is not flagged.

  Default: empty.

  [``any_RPC_okay : set[addr, string]``] Pairs of hosts and services for which any GETPORT access to the given service is allowed.

  `sun-rpc.mcast.net` Default:

          [NFS_world_servers, NFS_services],
          [sun-rpc.mcast.net, "ypserv"]

  The first of these allows access to any NFS service of any of the `NFS_world_servers`, using Bro's cross-product initialization feature (§ ). The second allows ypserv requests to the multicast address reserved for RPC multicasts.7.2

  [``suppress_pm_log : table[addr, string] of bool``] Do not generate real-time alerts for access by the given address for the given service. Note that unlike most Bro policy variables, this one is not `const` but is modified at run-time to add to it any host that invokes the walld RPC service, so that such access is only reported once for each host.

  Default: empty, but dynamic as discussed above.

##
`portmapper` functions

The standard script provides the following externally accessible functions:

  [``rpc_prog`(p: count): string``` ] Returns the name of the RPC program with the given number, if it's present in `rpc_programs`; otherwise returns the text `"unknown-`<`p`>`"`.

  [``pm_check_getport`(r: connection, prog: string): bool``` ] Checks a GETPORT request for the given program against the policy expressed by `RPC_okay_services`, `any_RPC_okay`, `RPC_okay`, and `RPC_okay_nets`, returning true if the request violates policy, false if it's allowed.

  [``pm_activity`(r: connection, log_it: bool)``` ] A bookkeeping function invoked when there's been portmapper activity on the given connection.

  The function records the connection via `record_connection`, unless it is a TCP connection (which will instead be recorded by `connection_finished`). If `log_it` is true then the function generates a real-time alert of the form:

  > rpc: `<`connection-id`>` `<`RPC-service`>` `<`r$addl`>`

  For example:

          972616255.679799 rpc: 65.174.102.21/832 > 182.7.9.47/portmapper
      	pm_getport: nfs -> 2049/udp

  However, it does not generate the alert if either the client host and service are present in `suppress_pm_log`, or if it already generated an alert in the past for the same client, server and service (to prevent alert cascades).

  [``pm_request`(r: connection, proc: string, addl: string, log_it: bool)``` ] Invoked when the given connection has made a portmapper request of some sort for the given RPC procedure `proc`. `addl` gives an annotation to add to the connection's `addl` field. If `log_it` is true, then connection should be logged; it will also be logged if the function determines that it is hot.

  The function first invokes `check_scan` and `check_hot` (with a mode of `CONN_ESTABLISHED`), unless `r` is a TCP connection, in which case these checks have already been made by `connection_established`. The function then adds `addl` to the connection's `addl` field, though if the field's length already exceeds 80 bytes, then it just tacks on `"..."` (unless already present). This last is necessary because Bro will sometimes see zillions of successive portmapper requests that all use the same connection ID, and these will each add to `addl` until it becomes unwieldy in size. Deficiency: Clearly, the byte limit of 80 should be adjustable.

  Finally, the function invokes `check_hot` with a mode of `CONN_FINISHED`, and `pm_activity` to finish up bookkeeping for the connection.

  No return value.

  [``pm_attempt`(r: connection, proc: string, status: count, addl: string, log_it: bool)``` ] Invoked when the given connection attempted to make a portmapper request of some sort, but the request failed or went unanswered. The arguments are the same as for `pm_request`, with the addition of `status`, which gives the RPC status code corresponding to why the attempt failed (see below).

  The function first invokes `check_scan` and `check_hot` (with a mode of `CONN_ATTEMPTED`), unless `r` is a TCP connection, in which case these checks have already been made by `connection_attempt`.

  Table 7.6: Types of RPC status codes.
  Status description | Meaning
  `"ok"` | The call succeeded.
  `"prog unavail"` | The call was for an RPC program that has not registered with the portmapper.
  `"mismatch"` | The call was for a version of the RPC program that has not registered with the portmapper.
  `"garbage args"` | The parameters in the call did not decode correctly.
  `"system err"` | A system error (such as out-of-memory) occurred when processing the call.
  `"timeout"` | No reply was received within 24 seconds of the request.
  `"auth error"` | The caller failed to authenticate to the server, or was not authorized to make the call.
  `"unknown"` | An unknown error occurred.

  The function then adds `addl` to the connection's `addl` field, along with a text description of the RPC status code, as given in Table 7.20.2.

  No return value.

##
`portmapper` event handlers

The standard script handles the following events:

  [``pm_request_null (r: connection)``] Invoked upon a successful portmapper request for the ``null'' procedure. The script invokes `pm_request` with `log_it=F`.

  [``pm_request_set (r: connection, m: pm_mapping, success: bool)``] Invoked upon a nominally successful portmapper request to set the portmapper binding `m`. The script invokes `pm_request` with `log_it=T`. `success` is true if the server honored the request, false otherwise; the script turns this into an annotation of `"ok"` or `"failed"`.

  The `pm_mapping` type (for `m`) has three fields, `program: count`, `version: count` and `p: port`, the port for the mapping of the given program and version. `pm_mapping`

  [``pm_request_unset (r: connection, m: pm_mapping, success: bool)``] Invoked upon a nominally successful portmapper request to remove a portmapper binding. The script invokes `pm_request` with `log_it=T`. `success` is true if the server honored the request, false otherwise; the script turns this into an annotation of `"ok"` or `"failed"`.

  [``pm_request_getport (r: connection, pr: pm_port_request, p: port)``] Invoked upon a successful portmapper request to look up a portmapper binding. `pr`, of type `pm_port_request`, has three fields: `program: count`, `version: count`, and `is_tcp: bool`, this last indicating whether the caller is request the TCP or UDP port, if the given program/version has mappings for both. The script invokes `pm_request` with `log_it` set according to the return value of `pm_check_getport` and an annotation of the mapping.

  [``pm_request_dump (r: connection, m: pm_mappings)``] Invoked upon a successful portmapper request to dump the portmapper bindings. The script invokes `pm_request` with `log_it=T` unless `RPC_dump_okay` indicates that the dump call is allowed. The script ignores `m`, which gives the mappings as a `table[count] of pm_mapping`, where the table index simply reflects the order in which the mappings were returned, starting with an index of 1. Deficiency: What the script should do, instead, is keep track of the mappings so that Bro can identify the service associated with connections for otherwise unknown ports.

  [``pm_request_callit (r: connection, pm_callit_request, p: port)``] Invoked upon a successful portmapper request to look up and call an RPC procedure. The script invokes `pm_request` with `log_it=T` unless the combination of the caller and the program are in `suppress_pm_log`. Finally, if the program called is walld, then the script adds the caller to `suppress_pm_log`.

  The `pm_callit_request` type has four fields: `pm_callit_request` `program: count`, `version: count`, `proc: count`, and `arg_size: count`. These reflect the procedure being looked up and called, and the size of the arguments being passed to it, respectively. Deficiency: Currently, the event engine does not do any analysis or refinement of the arguments passed to the procedure (such as making them available to the event handler) or the return value. `p` is the port value returned by the call.

  [``pm_attempt_null (r: connection, status: count)``] Invoked upon a failed portmapper request for the ``null'' procedure. `status` gives the reason for the failure. The script invokes `pm_attempt` with `log_it=T`.

  [``pm_attempt_set (r: connection, status: count, m: pm_mapping)``] Invoked upon a failed portmapper request to set the portmapper binding `m`. The script invokes `pm_attempt` with `log_it=T`.

  [``pm_attempt_unset (r: connection, status: count, m: pm_mapping)``] Invoked upon a failed portmapper request to remove a portmapper binding. The script invokes `pm_attempt` with `log_it=T`.

  [``pm_attempt_getport (r: connection, status: count, pr: pm_port_request)``] Invoked upon a failed portmapper request to look up a portmapper binding. `pr`, of type `pm_port_request`, has three fields: `program: count`, `version: count`, and `is_tcp: bool`, this last indicating whether the caller requested the TCP or UDP port. The script invokes `pm_attempt` with `log_it` set according to the return value of `pm_check_getport`.

  [``pm_attempt_dump (r: connection, status: count)``] Invoked upon a failed portmapper request to dump the portmapper bindings. The script invokes `pm_attempt` with `log_it=T` unless `RPC_dump_okay` indicates that the dump call is allowed.

  [``pm_attempt_callit (r: connection, status: count, pm_callit_request)``] Invoked upon a failed portmapper request to look up and call an RPC procedure. The script invokes `pm_attempt` with `log_it=T` unless the combination of the caller and the program are in `suppress_pm_log`. Finally, if the program called is walld, then the script adds the caller to `suppress_pm_log`.

  [``pm_bad_port (r: connection, bad_p: count)``] Invoked when a portmapper request or response includes an invalid port number. Since ports are represented by unsigned 4-byte integers, they can stray outside the allowed range of 0-65535 by being 65536. The script invokes `conn_weird_addl` with a weird tag of `"bad_pm_port"`.

#
The `analy` Analyzer

The `analy` analyzer provides a limited mechanism to use Bro to do statistical analysis on TCP connections. Its primary purpose is to demonstrate that Bro has applications to network traffic analysis beyond intrusion detection. It defines one event handler:

Table: `endpoint_stats` fields for summarizing connection endpoint statistics, all of type `count`.
Field | Meaning
`num_pkts` | The number of packets sent by the endpoint, as seen by the monitor. The endpoint may have sent others that the network dropped upstream from the monitor.
`num_rxmit` | The number of packets retransmitted by the endpoint, as seen by the monitor.
`num_rxmit_bytes` | The number of bytes retransmitted by the endpoint.
`num_in_order` | The number of packets sent by the endpoint that arrived at the monitor in order, where ``in order'' means in the same order as sent by the endpoint, rather than in sequence number. (Thus, a retransmission can arrive in order, by this definition.) Bro determines if the packet arrived in order by applying heuristics to the IP identification (ID) field, which in general will increase by a small amount between successive packets transmitted by an endpoint.
`num_OO` | The number of packets sent by the endpoint that arrived at the monitor out of order. See the previous entry for the definition of ``in order'', and hence ``out of order.''
`num_repl` | The number of extra copies of packets sent by the endpoint that arrived at the monitor. Bro considers a packet replicated if its IP ID field is the same as for the previous packet it saw from the endpoint. Using this definition, a replication is most likely caused by a network mechanism such as duplication of a packet by a router, rather than a transport mechanism such as retransmission, though some TCPs fully reuse packets when retransmitting them, including their IP ID field.
`endian_type` | Whether the advance of the IP ID field as seen by the monitor was consistent with big-endian (network order) addition, little-endian, or undetermined. The three values are represented by the Bro constants `ENDIAN_BIG`, `ENDIAN_LITTLE`, and `ENDIAN_UNKNOWN`. In addition, the value can be `ENDIAN_CONFUSED`, meaning that the monitor saw conflicting evidence for little- and big-endian.

  [``conn_stats (c: connection, os: endpoint_stats, rs: endpoint_stats)``] Invoked for each connection when it terminates (for whatever reason). `os` and `rs` are the statistics for the originator endpoint and the responder endpoint, respectively; Table 7.21 gives the different record fields.

#
The `weird` Module

The `weird` module processes unusual or exceptional events. A number of these ``shouldn't'' or even ``can't'' happen, yet they do. The general design philosophy of Bro is to check for such events whenever possible, because they can reflect incorrect assumptions (either Bro's or the user's), attempts by attackers to confuse the monitor and evade detection, broken hardware, misconfigured networks, and so on.

Weird events are divided into three categories, namely those pertaining to: connections; flows (a pair of hosts, but for which a specific connection cannot be identified); and network behavior (cannot be associated with a pair of hosts). These categories have a total of four event handlers: `conn_weird`, `conn_weird_addl`, `flow_weird`, and `net_weird`, and in the corresponding sections below we catalog the events handled by each. In addition, we separately catalog the events generated by the standard scripts themselves (§ ). Finally, two more weird events have their own handlers, in order to associate detailed information with the event: `rexmit_inconsistency` and `ack_above_hole`.

`weird_file` is the logging file that the module uses to record exceptional events. It defaults to `open_log_file("weird")`.

Note: While these events ``shouldn't'' happen, in reality they often do. For example, of the 73 listed below, a search of 10 months' worth of logs at LBNL shows that 42 were seen operationally. While some of the instances reflect attacks, the great majority are simply due to (i) buggy implementations, (ii) diverse use of the network, or (iii) Bro bugs or limitations. Accordingly, you may initially be inclined to log each instance, but don't be surprised to find that you soon decide to only record many of them in the `weird` file, or not record them at all. (For further discussion, see the section on ``crud'' in [Pa99].)

##
Actions for ``weird'' events

Table 7.8: Different types of possible actions to take for ``weird'' events.
Action | Meaning
`WEIRD_UNSPECIFIED` | No action specified.
`WEIRD_IGNORE` | Ignore the event.
`WEIRD_FILE` | Record the event to `weird_file`, if it has not been seen for these hosts before. (But see `weird_do_not_ignore_repeats`.)
`WEIRD_LOG_ALWAYS` | Record the event to `weird_file` and generate a real-time alert each time the event occurs.
`WEIRD_LOG_ONCE` | Record the event to `weird_file`; generate a real-time alert the first time the event occurs.
`WEIRD_LOG_PER_CONN` | Record the event to `weird_file`; generate a real-time alert the first time it occurs for a given connection.
`WEIRD_LOG_PER_ORIG` | Record the event to `weird_file`; generate a real-time alert the first time it occurs for a given originating host.

The general approach taken by the module is to categorize for each event the action to take when the event engine generates the event. Table 7.22.1 summarizes the different possible actions.

## `weird` variables

The standard `weird` script provides the following redefinable variables:

  [``weird_action : table[string] of count``] Maps different weird events to actions as given in Table 7.22.1.

  Default: as specified in `conn_weird`, `conn_weird_addl`, `flow_weird`, `net_weird`, and § . As usual, you can change particular values using refinement. For example:

      redef weird_action: table[string] of count += {
          [["bad_TCP_checksum", "bad_UDP_checksum"]] = WEIRD_IGNORE,
          ["fragment_overlap"] = WEIRD_LOG_PER_CONN,
      };

  would specify to ignore TCP and UDP checksum errors (rather than the default of `WEIRD_FILE`), and to alert on fragment overlaps once per connection in which they occur, rather than the default of `WEIRD_LOG_ALWAYS`.

  [``weird_action_filters : table[string] of function(c: connection): count``] Indexed by the name of a weird event, yields a function that when called for a given connection exhibiting the event, returns an action from Table 7.22.1. A return value of `WEIRD_UNSPECIFIED` means ``no special action, use the action you normally would.'' This variable thus allows arbitrary customization of the handling of particular events.

  Default: empty, for the `weird` analyzer itself. The `portmapper` analyzer redefines this variable as follows:

          redef weird_action_filters += {
              [["bad_RPC", "excess_RPC", "multiple_RPCs", "partial_RPC"]] =
                      RPC_weird_action_filter,
      };

  where `RPC_weird_action_filter` is a function internal to the analyzer that returns `WEIRD_FILE` if the originating host is in `RPC_okay_nets`, and `WEIRD_UNSPECIFIED` otherwise.

  [``weird_ignore_host : set[addr, string]``] Specifies that the analyzer should ignore the given weird event (named by the second index) if it involves the given address (as either originator or responder host).

  Default: empty.

  [``weird_do_not_ignore_repeats : set[string]``] Gives a set of weird events that, if their action is `WEIRD_FILE`, should still be recorded to the `weird_file` each time they occur.

  Default: the events relating to checksum errors, i.e., `"bad_IP_checksum"`, `"bad_TCP_checksum"`, `"bad_UDP_checksum"`, and `"bad_ICMP_checksum"`. These are recorded multiple times because it can prove handy to be able to track clusters of checksum errors.

## `weird` functions

The `weird` analyzer includes the following functions:

  [``report_weird`(t: time, name: string, id: string, action: count, no_log: bool)``` ] Processes an occurrence of the weird event `name` associated with the connection described by the string `id` (which may be empty if no connection is associated with the event). `action` is the action associated with the event. For `report_weird`, the only distinctions made between the different actions are that `WEIRD_IGNORE` causes the function to do nothing; any of `WEIRD_LOG_XXX` cause the function to log a message, unless `no_log` is true; and `WEIRD_UNSPECIFIED` causes the function to look up the action in `weird_action`. If the function does not find an action for the event, then it uses `WEIRD_LOG_ALWAYS` and prepends the log message with a pair of asterisks (```**`'') to flag that this event does not have a specified action.

  For `WEIRD_FILE`, `report_weird` only records the event once to the file, unless the given event is present in `weird_do_not_ignore_repeats`. Events with loggable actions are always recorded to `weird_file`.

  [``report_weird_conn`(t: time, name: string, id: string, c: connection)``` ] Processes an occurrence of the weird event `name` associated with the connection `c`, which is described by the string `id`.

  If `report_weird_conn` finds one of the hosts and the given event name in `weird_ignore_host`, then it does nothing. Then, if the event is in `weird_action`, then it looks up the event in `weird_action_filters` and invokes the corresponding function if present, otherwise taking the action from `weird_action`. It then implements the various flavors of `WEIRD_LOG_XXX` by not logging events more than once per connection, originator host, etc., though the events are still written to `weird_file`. Finally, the function invokes `report_weird` to do the actual recording and/or writing to `weird_file`.

  [``report_weird_orig`(t: time, name: string, id: string, orig: addr)``` ] Processes an occurrence of the weird event `name` associated with the source address `orig`. `id` textually describes the flow from `orig` to the destination, for example using `endpoint_id`.

  The function looks up the event name in `weird_action` and passes it along to `report_weird`.

## Events handled by `conn_weird`

  [``conn_weird (name: string, c: connection)``] Invoked for most ``weird'' events. `name` is the name of the weird event, and `c` is the connection with which it's associated.

`conn_weird` handles the following events, all of which have a default action of `WEIRD_FILE`:

  [`active_connection_reuse`] A new connection attempt (initial SYN) was seen for an already-established connection that has not yet terminated. [`bad_HTTP_reply`] The first line of a reply from an HTTP server did not include `HTTP/`version. [`bad_HTTP_version`] The first line of a request from an HTTP client did not include `HTTP/`version. [`bad_ICMP_checksum`] The checksum field in an ICMP packet was invalid. [`bad_rlogin_prolog`] The beginning of an Rlogin connection had a syntactical error. [`bad_RPC`] A Remote Procedure Call was ill-formed. [`bad_RPC_program`] A portmapper RPC call did not include the correct portmapper program number. [`bad_SYN_ack`] A TCP SYN acknowledgment (SYN-ack) did not acknowledge the sequence number sent in the initial SYN. [`bad_TCP_checksum`] A TCP packet had a bad checksum. [`bad_UDP_checksum`] A UDP packet had a bad checksum. [`baroque_SYN`] A TCP SYN was seen with an unlikely combination of other flags (the URGent pointer). [`blank_in_HTTP_request`] The URL in an HTTP request includes an embedded blank. [`connection_originator_SYN_ack`] A TCP endpoint that originated a connection by sending a SYN followed this up by sending a SYN-ack. [`data_after_reset`] After a TCP endpoint sent a RST to terminate a connection, it sent some data. [`data_before_established`] Before the connection was fully established, a TCP endpoint sent some data. [`excessive_RPC_len`] An RPC record sent over a TCP connection exceeded 8 KB. [`excess_RPC`] The sender of an RPC request or reply included leftover data beyond what the RPC parameters or result value themselves consumed. [`FIN_advanced_last_seq`] A TCP endpoint retransmitted a FIN with a higher sequence number than previously. [`FIN_after_reset`] A TCP endpoint sent a FIN after sending a RST. [`FIN_storm`] The monitor saw a flurry of FIN packets all sent on the same connection. A ``flurry'' is defined as 1,000 packets that arrived with less than 1 sec between successive FINs. Deficiency: Clearly, this numbers should be user-controllable. [`HTTP_unknown_method`] The method in an HTTP request was not GET, POST or HEAD. [`HTTP_version_mismatch`] A persistent HTTP connection sent a different version number for a subsequent item than it did initially. [`inappropriate_FIN`] A TCP endpoint sent a FIN before the connection was fully established. [`multiple_HTTP_request_elements`] An HTTP request included multiple methods. [`multiple_RPCs`] A TCP RPC stream included more than one remote procedure call. [`NUL_in_line`] A NUL (ASCII 0) was seen in a text stream that is expected to be free of NULs. Currently, the only such stream is that associated with an FTP control connection. [`originator_RPC_reply`] The originator (and hence presumed client) of an RPC connection sent an RPC reply (either instead of a request, or in addition to a request). [`partial_finger_request`] When a Finger connection terminated, it included a final line of unanalyzed text because the text was not newline-terminated. [`partial_ftp_request`] When an FTP connection terminated, it included a final line of unanalyzed text because the text was not newline-terminated. [`partial_ident_request`] When an IDENT connection terminated, it included a final line of unanalyzed text because the text was not newline-terminated. [`partial_portmapper_request`] A portmapper connection terminated with an unanalyzed request because the data stream was incomplete. [`partial_RPC`] An RPC was missing some required header information due to truncation. [`pending_data_when_closed`] A TCP connection closed even though not all of the data in it was analyzed due to a sequence hole. [`possible_split_routing`] Bro appears to be seeing only one direction of some bi-directional connections (§ ). This can also occur due to certain forms of stealth-scanning. [`premature_connection_reuse`] A TCP connection tuple is being reused less than 30 sec after its previous use. (The standard requires waiting minutes [RFC793, p. 27].) [`repeated_SYN_reply_wo_ack`] A TCP responder that replied to an initial SYN with a SYN-ack has subsequently sent a SYN without an acknowledgment. [`repeated_SYN_with_ack`] A TCP originator that sent an initial SYN has subsequently sent a SYN-ack. [`responder_RPC_call`] The responder (and hence presumed server) of an RPC connection sent an RPC request (either instead of a reply, or in addition to a reply). [`rlogin_text_after_rejected`] An Rlogin client sent additional text to an Rlogin server after the server already presumably rejected the client's service request. [`RPC_rexmit_inconsistency`] An RPC call was retransmitted, and the retransmitted call differed from the original call. This could reflect an attempt by an attacker to evade the monitor. Note: This type of inconsistency checking is not available for RPC replies because the transmission of the reply in general marks the end of the RPC connection, and the monitor deletes the connection state shortly afterward. [`RST_storm`] The monitor saw a flurry of RST packets all sent on the same connection. See `FIN_storm` for the definition of ``flurry.'' [`RST_with_data`] A TCP RST packet included data. This actually is allowed by the specification [RFC1122, 4.2.2.12]. Deficiency: This event should include the data. [`simultaneous_open`] The monitor saw a TCP simultaneous open, i.e., both endpoints sent initial SYNs to one another at the same time. While the specification allows this [RFC793, p. 30], none of the protocols analyzed by Bro should be using it. [`spontaneous_FIN`] A TCP endpoint sent a FIN packet without sending any previous packets. This event can reflect stealth-scanning, but can also occur when Bro has recently started up and has not seen other traffic on a connection and hence does not know that the connection already exists. [`spontaneous_RST`] A TCP endpoint sent a RST packet without sending any previous packets. As with `spontaneous_FIN`, this event can reflect either stealth scanning or a Bro start-up transient. [`SYN_after_close`] A TCP endpoint sent a SYN (connection initiation) after sending a FIN (connection termination), but before the connection fully closed. [`SYN_after_partial`] A TCP endpoint in a ``partial'' connection (§ ) sent a SYN. [`SYN_after_reset`] A TCP endpoint sent a SYN after sending a RST (reset connection). [`SYN_inside_connection`] A TCP endpoint sent a SYN during a connection (or partial connection) on which it had already sent data. [`SYN_seq_jump`] A TCP endpoint retransmitted a SYN or a SYN-ack, but with a different sequence number. [`SYN_with_data`] A TCP endpoint included data in a SYN packet it sent. Note, this can legitimately occur for T/TCP connections [RFC1644]. [`TCP_christmas`] A TCP endpoint sent a SYN packet that included the RST flag (a nonsensical combination). The term ``Christmas packet'' has been used in this context (particularly if other flags are set, too) because the packet's flags are ``lit up like a Christmas tree.'' [`UDP_datagram_length_mismatch`] The length field in a UDP header did not match the length field in the IP header. This could reflect an attempt by an attacker to evade the monitor. [`unpaired_RPC_response`] An RPC reply was seen for which no request was seen. This event could reflect a Bro start-up transient (it started running after the request was sent). [`unsolicited_SYN_response`] A TCP endpoint sent a SYN-ack without first receiving an initial SYN. This event could reflect a Bro start-up transient.

## Events handled by `conn_weird_addl`

  [``conn_weird_addl (name: string, c: connection, addl: string)``] Invoked for a few ``weird'' events that require an extra (string) argument to help clarify the event. Deficiency: It would likely be very handy if the general ``weird'' event handling was more flexible, with the ability to have various parameters associated with the events. Doing so will likely have to wait on general Bro mechanism for dealing with default parameters and/or polymorphic functions and event handlers.

`conn_weird_addl` handles the following events, all of which have a default action of `WEIRD_FILE`:

  [`bad_ident_reply`] A reply from an IDENT server was syntactically invalid. [`bad_ident_request`] A request to an IDENT server was syntactically invalid. [`ident_request_addendum`] An IDENT request included additional text beyond that forming the request itself.

## Events handled by `flow_weird`

  [``flow_weird (name: string, src: addr, dst: addr)``] is invoked for ``weird'' events that cannot be associated with a particular connection, but only with a pair of hosts, corresponding to a flow of packets from `src` to `dst`. Presently, all of these events deal with fragments.

`flow_weird` handles the following events:

  [`excessively_large_fragment`] A set of IP fragments reassembled to a maximum size exceeding 64,000 bytes. Note: Sizes between 64,000 and 65,535 bytes are allowed, strictly speaking, but are highly unlikely in legitimate traffic. Sizes above 65,535 bytes generally represent attempted denial-of-service attacks, due to IP implementations that crash upon receiving such impossibly-large fragment sets.

  Default: `WEIRD_LOG_ALWAYS`.

  [`excessively_small_fragment`] A fragment other than the last fragment in a set was less than 64 bytes in size. Note: The standard allows such small fragments, but their presence may reflect an attacker attempting to evade the monitor by splitting header information across multiple fragments.

  Default: `WEIRD_LOG_ALWAYS`.

  [`fragment_inconsistency`] A fragment overlaps with a previously sent fragment, and the two disagree on data they share in common. This event could reflect an attacker attempting to evade the monitor; it can also occur because Bro keeps previous fragments indefinitely (Deficiency: it needs to provide a means for flushing old fragments, otherwise it becomes vulnerable to a state-holding attack), and occasionally a fragment will overlap with one sent much earlier and long-since forgotten by the endpoints.

  Default: `WEIRD_LOG_ALWAYS`.

  [`fragment_overlap`] A fragment overlaps with a previously sent fragment. As for `fragment_inconsistency`, this event can occur due to Bro keeping previous fragments indefinitely. This event does not in general reflect a possible attempt at evasion.

  Default: `WEIRD_LOG_ALWAYS`.

  [`fragment_protocol_inconsistency`] Two fragments were seen for the same flow and IP ID which differed in their transport protocol (e.g., UDP, TCP). According to the specification, this is allowed [RFC791, p. 24], but its use appears highly unlikely.

  Default: `WEIRD_FILE`, because it is difficult to see how an attacker can exploit this anomaly.

  [`fragment_size_inconsistency`] A ``last fragment'' was seen twice, and the two disagree on how large the reassembled datagram should be. This event could reflect an attacker attempting to evade the monitor.

  Default: `WEIRD_FILE`, since it is more likely that this occurs due to a high volume flow of fragments wrapping the IP ID space than due to an actual attack.

  [`fragment_with_DF`] A fragment was seen with the ``Don't Fragment'' bit set in its header. While strictly speaking this is not illegal, and not impossible (a router could have fragmented a packet and then decided that the fragments should not be further fragmented), its presence is highly unusual.

  Default: `WEIRD_FILE`, because it's difficult to see how this could reflect malicious activity.

  [`incompletely_captured_fragment`] A fragment was seen whose length field is larger than the fragment datagram appearing on the monitored link.

  Default: `WEIRD_LOG_ALWAYS`.

## Events handled by `net_weird`

  [``net_weird (name: string)``] is invoked for ``weird'' events that cannot be associated with a particular connection or set of hosts. Except as noted, the default action for all such events is `WEIRD_FILE`.

`net_weird` handles the following events:

  [`bad_IP_checksum`] A packet had a bad IP header checksum.

  [`bad_TCP_header_len`] The length of the TCP header (which is itself specified in the header) was smaller than the minimum allowed size.

  [`internally_truncated_header`] A captured packet with a valid IP length field was smaller as actually recorded, such that the captured version of the packet was illegally small. This event may reflect an error in Bro's packet capture hardware or software.

  Default: `WEIRD_LOG_ALWAYS`, because this event can indicate a basic problem with Bro's packet capture.

  [`truncated_IP`] A captured packet either was too small to include a minimal IP header, or the full length as recorded by the packet capture library was smaller than the length as indicated by the IP header.

  [`truncated_header`] An IP datagram's header indicates a length smaller than that required for the indicated transport type (TCP, UDP, ICMP).

##
Events generated by the standard scripts

The following events are generated by the standard scripts themselves:

  [`bad_pm_port`] See `pm_bad_port`. Handled by `conn_weird_addl`, where the extra parameter is the text `"port <`bad-port`>"`.

  [`Land_attack`] A TCP connection attempt was seen with identical initiator and responder addresses and ports. This event likely reflects an attempted denial-of-service attack known as a ``Land'' attack. See `check_spoof`. Handled by `conn_weird`.

##
Additional handlers for ``weird'' events

In addition to the above, generalized events, Bro includes two specific events that are defined by themselves so they can include additional parameterization:

  [``rexmit_inconsistency (c: connection, t1: string, t2: string)``] Invoked when a retransmission associated with connection `c` differed in its data from the contents transmitted previously. `t1` gives the original data and `t2` the different retransmitted data.

  This event may reflect an attacker attempting to evade the monitor. Unfortunately, however, experience has shown that (i) inconsistent retransmissions do in fact happen due to (appalling) TCP implementation bugs, and (ii) once they occur, they tend to cascade, because often the source of the bug is that the two endpoints have become desynchronized.

  The handler logs the message in the format `"`id `rexmit inconsistency (<t1>) (<t2>)"` . However, the handler only logs the first instance of an inconsistency, due to the cascade problem mentioned above.

  Deficiency: The handler is not told which of the two connection endpoints was the faulty transmitter.

  [``ack_above_hole (c: connection, t1: string, t2: string)``] Invoked when Bro sees a TCP receiver acknowledge data above a sequence hole. In principle, this should never occur. Its presence generally means one of two things: (i) a TCP implementation with an appalling bug (these definitely exist), or (ii) a packet drop by Bro's packet capture facility, such that it never saw the data now being acknowledged.

  Because of the seriousness of this latter possibility, the handler logs a message `"ack above a hole"`. Note: You can often distinguish between a truly broken TCP acknowledgment and Bro dropping packets by the fact that in the latter case you generally see a cluster of ack-above-a-hole messages among otherwise unrelated connections.

  Deficiency: The handler is not told which of the two connection endpoints sent the acknowledgment.

#
The `icmp` Analyzer

#
The `stepping` Analyzer

#
The `ssh-stepping` Module

#
The `backdoor` Analyzer

#
The `interconn` Analyzer

#
Missing Documentation

This chapter holds stubs for subjects that have yet to be documented. Some of these are actually already somewhat covered elsewhere in the manual. In addition, a major missing piece for the manual is the Bro language itself; below we mention some Bro language topics that come up elsewhere in the current version of the manual.

#
The use of prefixes

#
The tcpdump save file that Bro writes

# The `bro.init` initialization file

# Assignment operators such as `+=`

#
The notion of redefinition/refinement

# The logging model

#
Timer management

#
SYN-FIN filtering

#
Split routing

#
Scan dropping

#
Operator precedence

#
Partial connections

#
Packet drops

#
The `@load` directive

#
Global statements

#
Inserting tables into tables

#
Demultiplexing

#
Bro init file

#
Hostnames vs. addresses

#
The hot-report script

# Use of libpcap/BPF

[MJ93,MLJ94]

# The problem of evasion

[PN98]

# Backscatter

#
Playing back traces

#
Discarders

#
Differences between this release and the previous one

# Alert cascade

# The need for subtyping

E.g., `src addr` vs. `dst addr`, perhaps using attributes.

# The need for CIDR masks

# The wish list

# Known bugs

## Bibliography

RFC2373
  R. Hinden and S. Deering, ``IP Version 6 Addressing Architecture,'' RFC 2373, Jul. 1998.

MJ93
  S. McCanne and V. Jacobson, ``The BSD Packet Filter: A New Architecture for User-level Packet Capture,'' Proc. 1993 Winter USENIX Conference, San Diego, CA.

MLJ94
  S. McCanne, C. Leres and V. Jacobson, `libpcap`, available via anonymous ftp to ftp.ee.lbl.gov, 1994.

Pa98
  V. Paxson, ``Bro: A System for Detecting Network Intruders in Real-Time,'' Proc. 7th USENIX Security Symposium, Jan. 1998.

Pa99
  V. Paxson, ``Bro: A System for Detecting Network Intruders in Real-Time,'' Computer Networks special issue on intrusion detection, 31(23-24), pp. 2435-2463, Dec. 1999.

PN98
  T. Ptacek and T. Newsham, ``Insertion, Evasion, and Denial of Service: Eluding Network Intrusion Detection,'' Secure Networks, Inc., http://www.aciri.org/vern/Ptacek-Newsham-Evasion-98.ps, Jan. 1998.

RFC791
  J. Postel, ``Internet Protocol,'' RFC 791, Sep. 1981.

RFC793
  J. Postel, ``Transmission Control Protocol,'' RFC 793, Sep. 1981.

RFC854
  J. Postel and J. Reynolds, ``Telnet Protocol Specification,'' RFC 854, May 1983.

RFC855
  J. Postel and J. Reynolds, ``Telnet Option Specifications,'' RFC 855, May 1983.

RFC959
  J. Postel and J. Reynolds, ``File Transfer Protocol (FTP),'' RFC 959, Oct. 1985.

RFC1013
  R. Scheifler, ``X Window System Protocol, version 11: Alpha update,'' RFC 1013, Apr. 1987.

RFC1094
  Sun Microsystems, ``NFS: Network File System Protocol specification,'' RFC 1094, Mar. 1989.

RFC1122
  B. Braden, ``Requirements for Internet hosts - communication layers,'' RFC 1122, Oct. 1989.

RFC1282
  B. Kantor, ``BSD Rlogin,'' RFC 1282, Dec. 1991.

RFC1288
  D. Zimmerman, ``The Finger User Information Protocol,'' RFC 1288, Dec. 1991.

RFC1413
  M. St. Johns, ``Identification Protocol,'' RFC 1413, Jan. 1993.

RFC1644
  B. Braden, ``T/TCP - TCP Extensions for Transactions Functional Specification,'' RFC 1644, Jul. 1994.

RFC1813
  B. Callaghan, B. Pawlowski, P. Staubach, ``NFS Version 3 Protocol Specification,'' RFC 1813, June 1995.

RFC1831
  R. Srinivasan, ``RPC: Remote Procedure Call Protocol Specification Version 2,'' RFC 1831, Aug. 1995.

RFC1832
  R. Srinivasan, ``XDR: External Data Representation Standard,'' RFC 1832, Aug. 1995.

RFC1939
  J. Myers and M. Rose, ``Post Office Protocol - Version 3,'' RFC 1939, May 1996.

RFC1945
  T. Berners-Lee, R. Fielding and H. Frystyk, ``Hypertext Transfer Protocol - HTTP/1.0,'' RFC 1945, May 1996.

RFC2616
  J. Mogul, H. Frystyk, L. Masinter, P. Leach, T. Berners-Lee, ``Hypertext Transfer Protocol - HTTP/1.1,'' RFC 2626, Jun. 1999.

YKSRL00
  T. Ylonen, T. Kivinen, M. Saarinen, T. Rinne and S. Lehtinen, ``SSH Connection Protocol,'' Internet Draft, draft-ietf-secsh-connect-07.txt, May 2000.

## Index

`!` operator
  Expressions
`!in` operator
  Expressions | Expressions
`$` record constructor operator
  Expressions | Expressions
`$` record field access operator
  Accessing Fields Using ```$`''
`(` operator
  Expressions
`)` operator
  Expressions
`+` operator
  Expressions
`++` operator
  Expressions
`+` addition operator
  Arithmetic Operators | Temporal Addition | Expressions
`+` unary operator
  Arithmetic Operators
`-` subtraction operator
  Arithmetic Operators | Temporal Subtraction | Expressions
`-` unary operator
  Arithmetic Operators | Temporal Negation
`*` multiplication operator
  Arithmetic Operators | Temporal Multiplication | Expressions
`/` division operator
  Arithmetic Operators | Temporal Division | Expressions
`+=` operator
  Filtering
`-` operator
  Expressions
`-` operator
  Expressions
`4Dgifts` username
  The `hot-ids` Module
`:` operator
  Expressions
`"|"|` short-circuit ``or''
  Logical Operators | Expressions
`&&` short-circuit ``and''
  Logical Operators | Expressions
`!` ``not'' operator
  Logical Operators
<
  Arithmetic Operators
`T`
  Boolean Constants
`F`
  Boolean Constants
`%`modulus operator
  Expressions
``%`` format
  Predefined Functions
`=` operator
  Expressions
`==` equality operator
  Comparison Operators | Exact Pattern Matching | Expressions | Expressions
`"!``` exact match negation
  Exact Pattern Matching
`` exact pattern match operator
  Exact Pattern Matching
`"!=` inequality operator
  Comparison Operators | Exact Pattern Matching | Expressions | Expressions
`<` less-than operator
  Comparison Operators | Expressions
`<=` less-or-equal operator
  Comparison Operators | Expressions
`>` greater-than operator
  Comparison Operators | Expressions
`>=` greater-or-equal operator
  Comparison Operators | Expressions
`?` operator
  Expressions
`?$` record field test
  Expressions
`[` operator
  Expressions | Expressions
`]` operator
  Expressions | Expressions
aborted execution
  Flags
absolute time
  Temporal Types
access
  allowable /16 network pairs
    `hot` variables
  allowable address pairs
    `hot` variables
  allowable services
    `hot` variables
  fatal inbound services
    `hot` variables
  forbidden attempted services
    `hot` variables
  forbidden inbound services
    `hot` variables
  forbidden services
    `hot` variables
  sensitive /24 destination networks
    `hot` variables
  sensitive /24 source networks
    `hot` variables
  sensitive destination addresses
    `hot` variables
  sensitive source addresses
    `hot` variables
  service allowed to a particular host
    `hot` variables
  service allowed to particular host pairs
    `hot` variables
`account_tried` event
  `scan` event handlers
`ack above a hole` (possible packet drop message)
  Additional handlers for ``weird''
`ack_above_hole` event
  General Processing Events | Additional handlers for ``weird''
acknowledgment holes
  Additional handlers for ``weird''
actions
  Actions for ``weird'' events | Actions for ``weird'' events | Actions for ``weird'' events | Actions for ``weird'' events | Actions for ``weird'' events | Actions for ``weird'' events | Actions for ``weird'' events
  `WEIRD_FILE`
    Actions for ``weird'' events
  `WEIRD_IGNORE`
    Actions for ``weird'' events
  `WEIRD_LOG_ALWAYS`
    Actions for ``weird'' events
  `WEIRD_LOG_ONCE`
    Actions for ``weird'' events
  `WEIRD_LOG_PER_CONN`
    Actions for ``weird'' events
  `WEIRD_LOG_PER_ORIG`
    Actions for ``weird'' events
  `WEIRD_UNSPECIFIED`
    Actions for ``weird'' events
`activating_encryption` event
  `login` event handlers
`active` module
  The `active` Module
`active_conn` variable
  The `active` Module
`active_connection` function
  Predefined Functions
`active_connection_reuse` (``weird'' event)
  Events handled by `conn_weird`
`active_file` function
  Predefined Functions
`add` keyword
  Statements
`add` statement
  Statements
`&add_func` attribute
  Refinement
`add_interface` function
  Predefined Functions
`add_tcpdump_filter` function
  Predefined Functions
addition
  numeric
    Arithmetic Operators
  temporal
    Temporal Addition
additional information associated with a connection
  The `connection` record | Connection summaries
`addl`
  The `connection` record
  `connection` field
    The `connection` record
`addl_web` variable
  `scan` variables
`addr`
  see types, `addr`
address masking
  Net Type | Predefined Functions | Predefined Functions
address scanning
  The `scan` Analyzer
address type
  Address Type to Address Operators
  constants
    Address Constants
  operators
    Address Operators
addresses
  hot destinations
    `hot` variables
  hot sources
    `hot` variables
  in a connection
    Connection summaries
  local
    Site variables | Site variables | Site variables | Site-specific functions
  mapping to hostnames
    The hf utility
  neighbor
    Site variables | Site variables | Site variables
`addrs`
  The `dns_mapping` record
  `dns_mapping` field
    The `dns_mapping` record
`\a` alert escape
  String Constants
`allow_16_net_pairs` variable
  `hot` variables
`allow_pairs` variable
  `hot` variables
`allow_services` variable
  `hot` variables
`allow_services_pairs` variable
  `hot` variables
`allow_services_to` variable
  `hot` variables
`allow_spoof_services` variable
  `hot` variables
allowable /16 network pairs
  `hot` variables
allowable address pairs
  `hot` variables
altering log files
  `login` variables
`always_hot_ids` variable
  The `hot-ids` Module
`always_hot_login_ids` variable
  `login` variables
`analy` analyzer
  The `analy` Analyzer
analysis
  bidirectional vs. unidirectional
    Events handled by `conn_weird`
  off-line
    Traffic traces | Flags | Predefined Functions | Connection functions
  on-line
    Live traffic | Flags | Predefined Variables | Predefined Functions | Connection functions
analyzers
  Analyzers and Events to The `interconn` Analyzer
  load
    Loading Analyzers
  `print-filter`
    Filtering | Filtering
  `print-filter`
    Filtering
  `conn`
    Generic Connection Analysis
  `tcp`
    no title
  `udp`
    no title
  `site`
    Site-specific information
  `hot`
    The `hot` Analyzer
  `scan`
    The `scan` Analyzer
  `finger`
    The `finger` Analyzer
  `ftp`
    The `ftp` Analyzer
  `http`
    The `http` Analyzer
  `ident`
    The `ident` Analyzer
  `login`
    The `login` Analyzer
  `portmapper`
    The `portmapper` Analyzer
  `analy`
    The `analy` Analyzer
  activating
    Activating an Analyzer
  application-specific
    The `finger` Analyzer to `portmapper` event handlers
  filtering
    Filtering to Filtering
  finger
    event handlers
      `finger` event handlers to `finger` event handlers
    variables
      `finger` variables to `finger` variables
  ftp
    event handlers
      `ftp` event handlers to `ftp` event handlers
    functions
      `ftp` functions to `ftp` functions
    variables
      `ftp` variables to `ftp` variables
  generic
    Generic Connection Analysis to Connection functions
  hot
    functions
      `hot` functions to `hot` functions
    variables
      `hot` variables to `hot` variables
  http
    event handlers
      `http` event handlers to `http` event handlers
    variables
      `http` variables to `http` variables
  ident
    event handlers
      `ident` event handlers to `ident` event handlers
    variables
      `ident` variables to `ident` variables
  instantiating
    Activating an Analyzer
  loading
    Loading Analyzers
  login
    event handlers
      `login` event handlers to `login` event handlers
    functions
      `login` functions to `login` functions
    variables
      `login` variables to `login` variables
  portmapper
    event handlers
      `portmapper` event handlers to `portmapper` event handlers
    functions
      `portmapper` functions to `portmapper` functions
    variables
      `portmapper` variables to `portmapper` variables
  scan
    event handlers
      `scan` event handlers to `scan` event handlers
    functions
      `scan` functions to `scan` functions
    variables
      `scan` variables to `scan` variables
  site-specific information
    Site-specific information to Site-specific functions
`&&` ``and'' operator
  Logical Operators | Expressions
anonymous function expression
  Expressions
anticode.com
  `login` variables
``any'' type
  The `any` type to The `any` type
  replacing with union type
    Predefined Functions
`any_RPC_okay` variable
  `portmapper` variables
appending to a file
  Predefined Functions
arithmetic expression
  Expressions
array
  associative
    Tables
  multi-dimensional
    Declaring Tables
as
  Files
  `RLIMIT_NOFILE`
    Files
ASCII
  as usual character set
    String Operators
assigning records
  Record Assignment to Record Assignment
assignment expression
  Expressions
associative array
  Tables
attack
  Land
    `hot` functions
attackers
  weenie
    The `hot-ids` Module
attacks
  smurf
    `login` variables
`ATTEMPT_INTERVAL` internal variable
  Generic TCP connection events
attempted connections
  Generic TCP connection events
attempted services
  forbidden
    `hot` variables
attributes
  Attributes
  `&add_func`
    Refinement
  `&create_expire`
    Table Attributes
  `&default`
    Table Attributes
  `&delete_func`
    Refinement
  `&expire_func`
    Table Attributes
  `&read_expire`
    Table Attributes
  record fields
    Record Assignment
  `&redef`
    Refinement
  `&write_expire`
    Table Attributes
`auth error` (RPC status code)
  `portmapper` functions
`auth-failed/` authentication annotation
  `login` event handlers
`auth/` authentication annotation
  `login` event handlers
authentication
  accepted
    `login` event handlers
  rejected
    `login` event handlers
  skipped
    `login` event handlers
authentication annotations
  `ident` event handlers | `login` event handlers | `login` event handlers | `login` event handlers | `login` event handlers | `login` event handlers
  `auth-failed/`
    `login` event handlers
  `auth/`
    `login` event handlers
  `confused/`
    `login` event handlers | `login` event handlers
  `ident/`
    `ident` event handlers
  `(skipped)`
    `login` event handlers
authentication dialog
  Predefined Functions | Predefined Functions | The `login` Analyzer | `login` analyzer confusion
  evasion
    `login` analyzer confusion
`authentication_accepted` event
  `login` event handlers
`authentication_rejected` event
  `login` event handlers
`authentication_skipped` event
  `login` event handlers
avoiding processing
  Predefined Functions
backdoor
  avoiding false positives
    `login` variables
  prompts
    `login` variables
  triggered by ephemeral port
    `login` variables
  triggered by terminal type
    `login` variables
`backdoor_prompts` variable
  `login` variables
backspace character
  Predefined Functions
`\b` backspace escape
  String Constants
bad address mask
  run-time error
    Predefined Functions
bad fmt date argument
  run-time error
    Predefined Functions
bad fmt editing character
  run-time error
    Predefined Functions
bad fmt field width
  run-time error
    Predefined Functions
bad fmt floating-point argument
  run-time error
    Predefined Functions
bad fmt format specifier
  run-time error
    Predefined Functions
bad fmt integer argument
  run-time error
    Predefined Functions
bad fmt precision
  run-time error
    Predefined Functions
`bad format`
  Predefined Functions
bad length argument (not a table or set)
  run-time error
    Predefined Functions
`bad second argument to mask_addr()`
  Predefined Functions
bad time
  `bad time`
    format conversion error
      Predefined Functions
`bad type for Date format`
  Predefined Functions
`bad type for floating-point format`
  Predefined Functions
`bad type for integer format`
  Predefined Functions
`bad_HTTP_reply` (``weird'' event)
  Events handled by `conn_weird`
`bad_HTTP_version` (``weird'' event)
  Events handled by `conn_weird`
`bad_ICMP_checksum` (``weird'' event)
  Events handled by `conn_weird`
`bad_ident_reply` (``weird'' event)
  Events handled by `conn_weird_addl`
`bad_ident_request` (``weird'' event)
  Events handled by `conn_weird_addl`
`bad_IP_checksum` (``weird'' event)
  Events handled by `net_weird`
`bad_option` event
  `login` event handlers
`bad_option_termination` event
  `login` event handlers
`bad_pm_port` (``weird'' event)
  Events generated by the
`bad_rlogin_prolog` (``weird'' event)
  Events handled by `conn_weird`
`bad_RPC` (``weird'' event)
  Events handled by `conn_weird`
`bad_RPC_program` (``weird'' event)
  Events handled by `conn_weird`
`bad_SYN_ack` (``weird'' event)
  Events handled by `conn_weird`
`bad_TCP_checksum` (``weird'' event)
  Events handled by `conn_weird`
`bad_TCP_header_len` (``weird'' event)
  Events handled by `net_weird`
`bad_UDP_checksum` (``weird'' event)
  Events handled by `conn_weird`
`baroque_SYN` (``weird'' event)
  Events handled by `conn_weird`
beginning time of a connection
  The `connection` record | Connection summaries
`\a` bell escape
  String Constants
bidirectional vs. unidirectional analysis
  Events handled by `conn_weird`
big endian
  Predefined Functions | The `analy` Analyzer
`/bin/eject` exploit
  `login` variables
BIND
  non-blocking DNS lookups
    The Bro source code
`blank_in_HTTP_request` (``weird'' event)
  Events handled by `conn_weird`
`bool`
  see types, `bool`
booleans
  Booleans to Logical Operators
Bourne shell
  Predefined Functions
BPF (Berkeley Packet Filter)
  tuning
    Tuning BPF
BPF buffers
  ensuring they are large
    Tuning BPF
`break` keyword
  Statements
`break` statement
  Statements
Bro
  checkpointing
    Flags
  execution aborted
    Flags
  flags
    `-P`
      The `dns` Module
    `-f`
      Flags
    `-h`
      Flags
    `-i`
      Flags
    `-p`
      Flags
    `-r`
      Flags
    `-w`
      Flags
    `-v`
      Flags
    `-F`
      Flags
    `-O`
      Flags
    `-P`
      Flags
    `-W`
      Flags
  installing
    Building and installing Bro
  interactive use
    Using Bro interactively
  not running as root
    Tuning BPF
  optimizer
    Flags
  private caches
    Flags | Flags
  references
    Introduction
  running
    Running Bro
  search path
    Run-time environment
  shadow
    Filtering
  source code
    The Bro source code
  startup slow due to compiling regular expressions
    Flags
  system configuration
    Tuning BPF
  usage
    Flags
  version
    Flags
  watchdog
    Flags
  web page
    The Bro source code
  wedging
    Flags
Bro bugs/limitations
  causing ``weird'' events
    The `weird` Module
`.bro` suffix
  Run-time environment
`.bro-dns-cache`
  The `dns` Module
`.bro-RE-cache.v1`
  Flags
`bro_done` event
  General Processing Events
`$BRO_ID` environment variable
  The `log` Module
`bro_init` event
  Filtering | Filtering | General Processing Events
`bro_log_file` variable
  Predefined Variables | The `log` Module
`$BRO_PREFIXES` environment variable
  Flags | Run-time environment
`bro_signal` event
  General Processing Events
`$BROPATH` environment variable
  Run-time environment
BS
  Predefined Functions
buffer overflow tools
  `login` variables
buffer size patch for libpcap
  Tuning BPF
buffers
  large for BPF
    Tuning BPF
buggy implementations
  causing ``weird'' events
    The `weird` Module
bugs
  `$` pattern operator not supported
    Embedded Pattern Matching
  appalling
    Additional handlers for ``weird'' | Additional handlers for ``weird''
  causing ``weird'' events
    The `weird` Module
  `tcpdump`
    Filtering
building Bro
  Building and installing Bro
`byte_len` function
  Predefined Functions
bytes in connection
  Connection summaries | Connection functions
caches
  Bro's private ones
    Flags
CALLIT portmapper call
  The `portmapper` Analyzer
can't open
  run-time error
    Run-time environment
`can_drop_connectivity` variable
  `scan` variables
`cannot create directory`
  Predefined Functions
`capture_filter` global variable
  Flags
`capture_filter` variable
  Predefined Variables | Filtering to Filtering
`\r` carriage return escape
  String Constants
casting
  not provided in Bro
    The `any` type
`cat` function
  Predefined Functions
Central Intelligence Agency
  detection
    `hot` variables
cf utility program
  no title
character set
  ASCII
    String Operators
`check_hot` function
  `hot` functions
`check_info` record
  `login` functions | `login` functions | `login` functions | `login` functions | `login` functions
  `forbidden`
    `login` functions
  `hot`
    `login` functions
  `hot_id`
    `login` functions
`check_scan` function
  `scan` functions
`check_spoof` function
  `hot` functions
checkpointing Bro
  Flags
checksum error
  ICMP
    Events handled by `conn_weird`
  IP
    Events handled by `net_weird`
  TCP
    Events handled by `conn_weird`
  UDP
    Events handled by `conn_weird`
Christmas packet
  Events handled by `conn_weird`
CIA detection
  `hot` variables
CIDR
  Net Type | Predefined Functions | Predefined Functions | Site variables
`clean` function
  Predefined Functions
cleanup event
  General Processing Events
client port
  triggering a backdoor
    `login` variables
clock time
  Predefined Functions | Predefined Functions
`close` function
  Predefined Functions
Cold Fusion exploits
  `http` variables
command shell
  Predefined Functions
  setuid root
    `login` variables
compiling Bro
  Building and installing Bro
compiling regular expressions
  Flags
completed connections
  Generic TCP connection events
compound statement
  Statements
concatenation of strings
  Predefined Functions
conditional expression
  Expressions
configuration options
  `-enable-brov6`
    The Bro source code
confused login analysis
  `login` analyzer confusion
`confused/` authentication annotation
  `login` event handlers | `login` event handlers
confusion of heuristics
  `login` analyzer confusion
`conn` analyzer
  Generic Connection Analysis
`conn_id` record
  The `connection` record | The `connection` record | The `connection` record | The `connection` record | The `connection` record | The `connection` record | The `connection` record
`conn_size` function
  Connection functions
`conn_state` function
  Connection functions
`conn_stats` event
  The `analy` Analyzer
`conn_weird` event
  Events handled by `conn_weird`
`conn_weird_addl` event
  Events handled by `conn_weird_addl`
connection
  additional information
    The `connection` record | Connection summaries
  addresses
    The `connection` record | The `connection` record | Connection summaries
  analysis
    Generic Connection Analysis | The `hot` Analyzer | The `analy` Analyzer
  attempt
    Generic TCP connection events
  bytes
    The `connection` record | Connection summaries | Connection functions
  completion
    Generic TCP connection events | Generic TCP connection events
  definitions
    Definitions of connections
  detecting sensitive
    `hot` functions
  duration
    The `connection` record | Connection summaries
  establishment
    Generic TCP connection events
  events
    Generic TCP connection events
  finished
    Generic TCP connection events
  flags
    Connection summaries
  functions
    Connection functions | Connection functions
  generic analysis
    Generic Connection Analysis
  half finished
    Generic TCP connection events
  hosts
    Connection summaries
  hot
    The `connection` record | Connection functions | `login` functions | `login` functions
  hot analysis
    The `hot` Analyzer
  ICMP
    Definitions of connections
  ID
    Connection functions | Connection functions
  initiator
    The `connection` record | The `connection` record
  logging
    Connection functions
  new
    Generic TCP connection events
  non-existing
    Run-time errors for non-existing
  originator
    The `connection` record | The `connection` record
  partial
    Generic TCP connection events
  partial close
    Generic TCP connection events
  pending
    Generic TCP connection events
  ports
    The `connection` record | The `connection` record
  recording
    Connection functions
  rejected
    Generic TCP connection events
  reset
    Generic TCP connection events
  reuse
    Events handled by `conn_weird`
  sensitivity
    The `connection` record
  sequence numbers
    Predefined Functions | Predefined Functions
  service
    The `connection` record | Connection summaries | Connection functions | Connection functions
  simultaneous open
    Events handled by `conn_weird`
  size
    The `connection` record | Connection summaries | Connection functions
  start time
    The `connection` record | Connection summaries
  state
    The `connection` record | Connection summaries | Connection functions
  summaries
    Connection summaries
  TCP
    Definitions of connections
  terminating with extreme prejudice
    Connection functions
  testing for existence
    Predefined Functions
  UDP
    Definitions of connections
connection events
  TCP-specific
    Generic TCP connection events
`connection id is not a known connection`
  Predefined Functions | Run-time errors for non-existing
`connection id is not a known login connection`
  Predefined Functions | Predefined Functions
`connection` record
  The `connection` record | The `connection` record | The `connection` record | The `connection` record | The `connection` record | The `connection` record | The `connection` record | The `connection` record | The `connection` record | The `connection` record | The `connection` record
connection size
  undetermined for RST termination
    `ftp` variables
connection states
  Connection summaries | Connection summaries | Connection summaries | Connection summaries | Connection summaries | Connection summaries | Connection summaries | Connection summaries | Connection summaries | Connection summaries | Connection summaries | Connection summaries | Connection summaries
  `OTH`
    Connection summaries
  `REJ`
    Connection summaries
  `RSTO`
    Connection summaries
  `RSTOS0`
    Connection summaries
  `RSTR`
    Connection summaries
  `RSTRH`
    Connection summaries
  `S0`
    Connection summaries
  `S1`
    Connection summaries
  `S2`
    Connection summaries
  `S3`
    Connection summaries
  `SF`
    Connection summaries
  `SH`
    Connection summaries
  `SHR`
    Connection summaries
connection summary files
  Connection summaries | Connection summaries
  `red`
    Connection summaries | Connection summaries
`connection_attempt` event
  Generic TCP connection events
`connection_established` event
  Generic TCP connection events | `login` event handlers
`connection_finished` event
  Generic TCP connection events
`connection_half_finished` event
  Generic TCP connection events
`connection_originator_SYN_ack` (``weird'' event)
  Events handled by `conn_weird`
`connection_partial_close` event
  Generic TCP connection events
`connection_pending` event
  Generic TCP connection events
`connection_record` function
  Predefined Functions
`connection_rejected` event
  Generic TCP connection events
`connection_reset` event
  Generic TCP connection events
connectivity
  dropping
    `scan` variables | `scan` functions
`const` statement
  Statements
`const` variable declaration
  Modifiability
constant expression
  Expressions
constant variables
  Statements
constants
  The `analy` Analyzer | The `analy` Analyzer | The `analy` Analyzer | The `analy` Analyzer
  address
    Address Constants
  boolean
    Boolean Constants
  count
    Numeric Constants
  `ENDIAN_BIG`
    The `analy` Analyzer
  `ENDIAN_CONFUSED`
    The `analy` Analyzer
  `ENDIAN_LITTLE`
    The `analy` Analyzer
  `ENDIAN_UNKNOWN`
    The `analy` Analyzer
  floating-point
    Numeric Constants
  hostname
    Address Constants
  integer
    Numeric Constants
  interval
    Temporal Constants to Temporal Constants
  net
    Net Constants
  pattern
    Pattern Constants to Pattern Constants
  port
    Port Constants
  record
    Record Constants to Record Constants
  string
    String Constants to String Constants
  temporal
    Temporal Constants
  time
    Temporal Constants to Temporal Constants
`contains_string` function
  Predefined Functions
`CONTENTS_BOTH` direction
  Predefined Functions
`CONTENTS_NONE` direction
  Predefined Functions
`CONTENTS_ORIG` direction
  Predefined Functions
`CONTENTS_RESP` direction
  Predefined Functions
control packets (SYN/FIN/RST)
  Flags | The `tcp` analyzer
`conversion of non-IPv4 address to net`
  Predefined Functions
converting an IPv6 address to net
  run-time error
    Predefined Functions
copy
  shallow vs. deep
    Record Assignment | Table Assignment
corrupted packets
  Events handled by `conn_weird` | Events handled by `net_weird`
`count`
  see types, `count`
`count` maximum
  Predefined Functions
`count` minimum
  Predefined Functions
`&create_expire` attribute
  Table Attributes
creating directories
  Predefined Functions
`creation_time`
  The `dns_mapping` record
  `dns_mapping` field
    The `dns_mapping` record
crud
  Generic TCP connection events | The `weird` Module
`current_time` function
  Predefined Functions
`d` format
  Predefined Functions | Predefined Functions
`daemon` username
  The `hot-ids` Module | `ident` variables
daemons
  as innocuous user names
    `ident` variables
data
  unanalyzed
    Events handled by `conn_weird`
`data_after_reset` (``weird'' event)
  Events handled by `conn_weird`
`data_before_established` (``weird'' event)
  Events handled by `conn_weird`
`day` interval unit
  Temporal Constants
debugging
  filtering problems
    Filtering
decrement expressions
  Expressions
deep copy
  Record Assignment | Table Assignment
default
  filtering
    Filtering
`&default` attribute
  Table Attributes
default values
  Table Attributes
DEL
  Predefined Functions | Predefined Functions
delete character
  Predefined Functions
`delete` keyword
  Statements
`delete` statement
  Statements
`&delete_func` attribute
  Refinement
`demux` module
  The `demux` Module
`demux_conn` function
  The `demux` Module
denial of service
  excessively large fragments
    Events handled by `flow_weird`
  Land attack
    Events generated by the
detecting scans
  The `scan` Analyzer
detecting sensitive connections
  `hot` functions
`determine_service` function
  Connection functions
/dev/bpf
  Tuning BPF
`direct_login_prompts` variable
  Predefined Variables | `login` variables
directions
  Predefined Functions | Predefined Functions | Predefined Functions | Predefined Functions
  `CONTENTS_BOTH`
    Predefined Functions
  `CONTENTS_NONE`
    Predefined Functions
  `CONTENTS_ORIG`
    Predefined Functions
  `CONTENTS_RESP`
    Predefined Functions
directories
  creating
    Predefined Functions
directory names
  sensitive
    `login` variables
`discarder_check_icmp` function
  Predefined Functions
`discarder_check_ip` function
  Predefined Functions
`discarder_check_tcp` function
  Predefined Functions
`discarder_check_udp` function
  Predefined Functions
`discarder_maxlen` variable
  Predefined Variables
diverse network use
  causing ``weird'' events
    The `weird` Module
division
  numeric
    Arithmetic Operators
  temporal
    Temporal Division
DMZ
  spoof detection
    `hot` variables
DNS
  Bro's private cache
    The `dns` Module
    forcing access to
      Flags
  mappings
    The `dns_mapping` record
DNS lookups
  non-blocking
    The Bro source code
`dns` module
  The `dns` Module
`dns_interesting_changes` variable
  `dns` variables
`dns_mapping` record
  no title | The `dns_mapping` record | The `dns_mapping` record | The `dns_mapping` record | The `dns_mapping` record | The `dns_mapping` record | The `dns_mapping` record | The `dns_mapping` record | The `dns_mapping` record
`dns_mapping_altered` event
  `dns` event handlers
`dns_mapping_lost_name` event
  `dns` event handlers
`dns_mapping_name_changed` event
  `dns` event handlers
`dns_mapping_new_name` event
  `dns` event handlers
`dns_mapping_unverified` event
  `dns` event handlers
`dns_mapping_valid` event
  `dns` event handlers
`done_with_network` global variable
  Expressions
`done_with_network` variable
  Predefined Variables
dotted quads
  The hf utility
`double`
  see types, `double`
`double` maximum
  Predefined Functions
`double` minimum
  Predefined Functions
drop-connectivity shell script
  `scan` functions
`drop_address` function
  `scan` functions
dropping connectivity
  `scan` variables | `scan` functions
DUMP portmapper call
  The `portmapper` Analyzer
`duration`
  The `connection` record
  `connection` field
    The `connection` record
duration of a connection
  The `connection` record | Connection summaries
dynamic defaults
  Table Attributes
`e` format
  Predefined Functions
`edit` function
  Predefined Functions
`edit_and_check_line` function
  `login` functions
`edit_and_check_password` function
  `login` functions
`edit_and_check_user` function
  `login` functions
`edited_input_trouble` variable
  `login` variables
editing
  Predefined Functions
`eggdrop` sensitive filename
  `ftp` variables
`eggdrop` sensitive login input
  `login` variables
`eject` exploit
  `login` variables
`else` keyword
  Statements
embedded NUL
  run-time error
    Run-time errors for strings
`-enable-brov6` configuration option
  The Bro source code
encrypted login sessions
  `login` event handlers
encryption
  leading to ``excessive lines''
    `login` event handlers
endian issues
  Predefined Functions | The `analy` Analyzer
`ENDIAN_BIG` constant
  The `analy` Analyzer
`ENDIAN_CONFUSED` constant
  The `analy` Analyzer
`ENDIAN_LITTLE` constant
  The `analy` Analyzer
`endian_type` statistic
  The `analy` Analyzer
`ENDIAN_UNKNOWN` constant
  The `analy` Analyzer
`endpoint` record
  The `connection` record | The `connection` record | The `connection` record | The `connection` record | The `connection` record | Connection summaries
`endpoint_id` function
  The `port-name` Module
`enum`
  see types, `enum` | see types, `enum`
enumerations
  Enumerations to Enumerations
environment
  accessing
    Predefined Functions
  responder
    `login` analyzer confusion
  Telnet options
    `login` analyzer confusion
environment variables
  `$BRO_ID`
    The `log` Module
  `$BRO_PREFIXES`
    Flags | Run-time environment
  `$BROPATH`
    Run-time environment
  `$USER`
    `login` analyzer confusion
ephemeral port
  Connection functions
  triggering a backdoor
    `login` variables
ephemeral ports
  confused with sensitive services
    `hot` variables
equality expression
  Expressions
escape sequences
  String Constants
established connections
  Generic TCP connection events
/etc/inetd.conf
  `hot` variables
/etc/passwd
  `http` variables
/etc/shadow
  `http` variables
evasion
  authentication dialog
    The `login` Analyzer | `login` analyzer confusion
  excessively small fragments
    Events handled by `flow_weird`
  inconsistent fragment size
    Events handled by `flow_weird`
  inconsistent fragments
    Events handled by `flow_weird`
  inconsistent RPC retransmission
    Events handled by `conn_weird`
  inconsistent TCP retransmission
    Additional handlers for ``weird''
  inserting NULs
    String Constants
  length mismatch
    Events handled by `conn_weird`
  using tunneling
    `login` event handlers
`event`
  see types, `event`
event engine
  Event handlers
event handler
  invocation
    Event handlers
event handlers
  Event handlers to Event handlers
event handling
  weird
    Events handled by `conn_weird` to Additional handlers for ``weird''
`event` keyword
  Statements
event scheduling expression
  Expressions
`event` statement
  Statements
event type
  Event handlers to Event handlers
events
  `bro_init`
    Filtering | Filtering
  `bro_init`
    General Processing Events
  `net_done`
    General Processing Events
  `bro_done`
    General Processing Events
  `bro_signal`
    General Processing Events
  `net_stats_update`
    General Processing Events
  `ack_above_hole`
    General Processing Events
  `new_connection`
    Generic TCP connection events
  `connection_established`
    Generic TCP connection events
  `connection_attempt`
    Generic TCP connection events
  `partial_connection`
    Generic TCP connection events
  `connection_finished`
    Generic TCP connection events
  `connection_rejected`
    Generic TCP connection events
  `connection_half_finished`
    Generic TCP connection events
  `connection_reset`
    Generic TCP connection events
  `connection_partial_close`
    Generic TCP connection events
  `connection_pending`
    Generic TCP connection events
  `udp_request`
    The `udp` analyzer
  `udp_reply`
    The `udp` analyzer
  `account_tried`
    `scan` event handlers
  `dns_mapping_valid`
    `dns` event handlers
  `dns_mapping_unverified`
    `dns` event handlers
  `dns_mapping_new_name`
    `dns` event handlers
  `dns_mapping_lost_name`
    `dns` event handlers
  `dns_mapping_name_changed`
    `dns` event handlers
  `dns_mapping_altered`
    `dns` event handlers
  `finger_request`
    `finger` event handlers
  `finger_reply`
    `finger` event handlers
  `ftp_request`
    `ftp` event handlers
  `ftp_reply`
    `ftp` event handlers
  `http_request`
    `http` event handlers
  `ident_request`
    `ident` event handlers
  `ident_reply`
    `ident` event handlers
  `ident_error`
    `ident` event handlers
  `login_failure`
    `login` event handlers
  `login_success`
    `login` event handlers
  `login_input_line`
    `login` event handlers
  `login_output_line`
    `login` event handlers
  `login_confused`
    `login` event handlers
  `login_confused_text`
    `login` event handlers
  `login_terminal`
    `login` event handlers
  `excessive_line`
    `login` event handlers
  `inconsistent_option`
    `login` event handlers
  `bad_option`
    `login` event handlers
  `bad_option_termination`
    `login` event handlers
  `authentication_accepted`
    `login` event handlers
  `authentication_rejected`
    `login` event handlers
  `authentication_skipped`
    `login` event handlers
  `connection_established`
    `login` event handlers
  `partial_connection`
    `login` event handlers
  `activating_encryption`
    `login` event handlers
  `pm_request_null`
    `portmapper` event handlers
  `pm_request_set`
    `portmapper` event handlers
  `pm_request_unset`
    `portmapper` event handlers
  `pm_request_getport`
    `portmapper` event handlers
  `pm_request_dump`
    `portmapper` event handlers
  `pm_request_callit`
    `portmapper` event handlers
  `pm_attempt_null`
    `portmapper` event handlers
  `pm_attempt_set`
    `portmapper` event handlers
  `pm_attempt_unset`
    `portmapper` event handlers
  `pm_attempt_getport`
    `portmapper` event handlers
  `pm_attempt_dump`
    `portmapper` event handlers
  `pm_attempt_callit`
    `portmapper` event handlers
  `pm_bad_port`
    `portmapper` event handlers
  `conn_stats`
    The `analy` Analyzer
  `conn_weird`
    Events handled by `conn_weird`
  `conn_weird_addl`
    Events handled by `conn_weird_addl`
  `flow_weird`
    Events handled by `flow_weird`
  `net_weird`
    Events handled by `net_weird`
  `rexmit_inconsistency`
    Additional handlers for ``weird''
  `ack_above_hole`
    Additional handlers for ``weird''
  exceptional
    The `weird` Module to Additional handlers for ``weird''
  finish
    General Processing Events | General Processing Events
  general Bro processing
    General Processing Events
  generic TCP connection
    Generic TCP connection events
  initialization
    General Processing Events
  scheduling
    Expressions
  startup
    General Processing Events
  termination
    General Processing Events | General Processing Events
exceptional events
  The `weird` Module to Additional handlers for ``weird''
`excess_RPC` (``weird'' event)
  Events handled by `conn_weird`
`excessive_line` event
  `login` event handlers
`excessive_RPC_len` (``weird'' event)
  Events handled by `conn_weird`
`excessive_typeahead` (login confusion state)
  `login` analyzer confusion
excessively long lines
  `login` event handlers
`excessively_large_fragment` (``weird'' event)
  Events handled by `flow_weird`
`excessively_small_fragment` (``weird'' event)
  Events handled by `flow_weird`
excluding hosts
  Filtering
executables
  running
    Predefined Functions
`exit` function
  Predefined Functions
`expanded_line`
  `login` functions
  `check_info` field
    `login` functions
expiration
  timer
    Expressions | Predefined Variables
`&expire_func` attribute
  Table Attributes
explicit typing
  Typing
exploit tools
  `login` variables
  `smashdu.c`
    `login` variables
exploits
  `login` variables | `login` variables | `login` variables
  `/bin/eject`
    `login` variables
  buffer overflow
    `login` variables
  `eject`
    `login` variables
  `loadmodule`
    `login` variables
  Unix
    `login` variables
expression statement
  Statements
expressions
  Expressions to Expressions
  parenthesized
    Expressions
  constant
    Expressions
  variable
    Expressions
  increment
    Expressions
  decrement
    Expressions
  negation
    Expressions
  positivation
    Expressions
  arithmetic
    Expressions
  logical
    Expressions
  equality
    Expressions
  relational
    Expressions
  conditional
    Expressions
  assignment
    Expressions
  function call
    Expressions
  anonymous function
    Expressions
  event scheduling
    Expressions
  index
    Expressions
  membership
    Expressions
  pattern matching
    Expressions
  record field access
    Expressions
  record constructor
    Expressions
  record field test
    Expressions
`extra_repeat_text` (login confusion state)
  `login` analyzer confusion
`EZsetup` username
  The `hot-ids` Module
`-F` flag
  Flags | Flags
`f` format
  Predefined Functions
failure of heuristics
  `login` analyzer confusion
fatal run-time error
  non-existing connection
    Predefined Functions
fetch utility
  `login` variables
fflush
  Predefined Functions
field attributes
  Record Assignment
`\f` formfeed escape
  String Constants
`file`
  see types, `file`
file type
  Files to Files
filenames
  sensitive
    `ftp` variables | `login` variables
files
  appending
    Predefined Functions
  opening
    Predefined Functions | Predefined Functions
  testing if open
    Predefined Functions
filtering
  default
    Filtering
filters
  Filtering to Filtering
  displaying
    Filtering
  errors
    Filtering
FIN control packet
  Flags | The `tcp` analyzer
`FIN_advanced_last_seq` (``weird'' event)
  Events handled by `conn_weird`
`FIN_after_reset` (``weird'' event)
  Events handled by `conn_weird`
`FIN_storm` (``weird'' event)
  Events handled by `conn_weird`
Finger
  analysis
    The `finger` Analyzer
  weird events
    Events handled by `conn_weird`
`finger` analyzer
  The `finger` Analyzer
`finger_reply` event
  `finger` event handlers
`finger_request` event
  `finger` event handlers
finish event
  General Processing Events | General Processing Events
firewall
  reactive
    `scan` variables | `scan` functions
`flag_rejected_service` variable
  `hot` variables
`flag_successful_inbound_service` variable
  `hot` variables
`flag_successful_service` variable
  `hot` variables
flags
  `-P`
    The `dns` Module
  `-f`
    Flags
  `-h`
    Flags
  `-i`
    Flags
  `-p`
    Flags
  `-r`
    Flags
  `-w`
    Flags
  `-v`
    Flags
  `-F`
    Flags
  `-O`
    Flags
  `-P`
    Flags
  `-W`
    Flags
flags of connection
  Connection summaries
flex utility
  Pattern Constants
`flow_weird` event
  Events handled by `flow_weird`
`flush_all` function
  Predefined Functions
`fmt` function
  Predefined Functions
`for` keyword
  Statements
`for` statement
  Statements
`forbidden check_info` record
  `login` functions
`forbidden_id_patterns` variable
  The `hot-ids` Module
`forbidden_ids` variable
  The `hot-ids` Module
`forbidden_ids_if_no_password` variable
  The `hot-ids` Module
forcing access to Bro's private DNS cache
  Flags
format
  ``%``
    Predefined Functions
  `d`
    Predefined Functions | Predefined Functions
  `e`
    Predefined Functions
  `f`
    Predefined Functions
  `g`
    Predefined Functions
  precision
    Predefined Functions
  width
    Predefined Functions
formatting text
  Predefined Functions
`.forward`
  `ftp` variables
`frag` module
  The `frag` Module
fragment reassembly
  The `frag` Module
`fragment_inconsistency` (``weird'' event)
  Events handled by `flow_weird`
`fragment_overlap` (``weird'' event)
  Events handled by `flow_weird`
`fragment_protocol_inconsistency` (``weird'' event)
  Events handled by `flow_weird`
`fragment_size_inconsistency` (``weird'' event)
  Events handled by `flow_weird`
`fragment_with_DF` (``weird'' event)
  Events handled by `flow_weird`
fragments
  excessively large
    Events handled by `flow_weird`
  excessively small
    Events handled by `flow_weird`
  inconsistent
    Events handled by `flow_weird`
  inconsistent protocols
    Events handled by `flow_weird`
  inconsistent sizes
    Events handled by `flow_weird`
  overlapping
    Events handled by `flow_weird`
  TCP vs. UDP
    The `frag` Module
frogs
  dissecting
    `http` variables
FTP
  analysis
    The `ftp` Analyzer
  ephemeral ports confused with sensitive services
    `hot` variables
  log file
    `ftp` variables
  session information
    The `ftp_session_info` record
  weird events
    Events handled by `conn_weird`
`ftp` analyzer
  The `ftp` Analyzer
`ftp` session summary file
  `ftp` variables
`ftp_guest_ids` variable
  `ftp` variables
`ftp_hot_files` variable
  `ftp` variables
`ftp_hot_guest_files` variable
  `ftp` variables
`ftp_not_actually_hot_files` variable
  `ftp` variables
`ftp_port` record
  Predefined Functions | Predefined Functions
`ftp_reply` event
  `ftp` event handlers
`ftp_request` event
  `ftp` event handlers
`ftp_session_info` record
  no title | The `ftp_session_info` record | The `ftp_session_info` record | The `ftp_session_info` record | The `ftp_session_info` record | The `ftp_session_info` record | The `ftp_session_info` record | The `ftp_session_info` record | The `ftp_session_info` record | The `ftp_session_info` record
`ftp_skip_hot` variable
  `ftp` variables
`full_id_string` function
  Connection functions
`function`
  see types, `function`
function call expression
  Expressions
function invocation
  Expressions
`function` keyword
  Expressions
function type
  Functions to Functions
functions
  Functions to Functions
  `active_connection`
    Predefined Functions
  `active_file`
    Predefined Functions
  `add_interface`
    Predefined Functions
  `add_tcpdump_filter`
    Predefined Functions
  `log_hook`
    Predefined Functions
  `byte_len`
    Predefined Functions
  `cat`
    Predefined Functions
  `clean`
    Predefined Functions
  `close`
    Predefined Functions
  `connection_record`
    Predefined Functions
  `contains_string`
    Predefined Functions
  `current_time`
    Predefined Functions
  `discarder_check_icmp`
    Predefined Functions
  `discarder_check_ip`
    Predefined Functions
  `discarder_check_tcp`
    Predefined Functions
  `discarder_check_udp`
    Predefined Functions
  `edit`
    Predefined Functions
  `exit`
    Predefined Functions
  `flush_all`
    Predefined Functions
  `fmt`
    Predefined Functions
  `get_login_state`
    Predefined Functions
  `get_orig_seq`
    Predefined Functions
  `get_resp_seq`
    Predefined Functions
  `getenv`
    Predefined Functions
  `is_tcp_port`
    Predefined Functions
  `length`
    Predefined Functions
  `log_file_name`
    Predefined Functions
  `mask_addr`
    Predefined Functions
  `max_count`
    Predefined Functions
  `max_double`
    Predefined Functions
  `max_interval`
    Predefined Functions
  `min_count`
    Predefined Functions
  `min_double`
    Predefined Functions
  `min_interval`
    Predefined Functions
  `mkdir`
    Predefined Functions
  `network_time`
    Predefined Functions
  `open`
    Predefined Functions
  `open_for_append`
    Predefined Functions
  `open_log_file`
    Predefined Functions
  `parse_ftp_pasv`
    Predefined Functions
  `parse_ftp_port`
    Predefined Functions
  `reading_live_traffic`
    Predefined Functions
  `set_buf`
    Predefined Functions
  `set_contents_file`
    Predefined Functions
  `set_login_state`
    Predefined Functions
  `set_record_packets`
    Predefined Functions
  `skip_further_processing`
    Predefined Functions
  `sub_bytes`
    Predefined Functions
  `system`
    Predefined Functions
  `to_lower`
    Predefined Functions
  `to_net`
    Predefined Functions
  `to_upper`
    Predefined Functions
  `conn_size`
    Connection functions
  `conn_state`
    Connection functions
  `determine_service`
    Connection functions
  `full_id_string`
    Connection functions
  `id_string`
    Connection functions
  `log_hot_conn`
    Connection functions
  `record_connection`
    Connection functions
  `service_name`
    Connection functions
  `terminate_connection`
    Connection functions
  `is_local_addr`
    Site-specific functions
  `check_spoof`
    `hot` functions
  `check_hot`
    `hot` functions
  `drop_address`
    `scan` functions
  `check_scan`
    `scan` functions
  `endpoint_id`
    The `port-name` Module
  `log_hook`
    The `log` Module | The `log` Module
  `log_hook`
    The `log` Module
  `demux_conn`
    The `demux` Module
  `is_ftp_data_conn`
    `ftp` functions
  `is_login_conn`
    `login` functions
  `hot_login`
    `login` functions
  `is_hot_id`
    `login` functions
  `is_forbidden_id`
    `login` functions
  `edit_and_check_line`
    `login` functions
  `edit_and_check_user`
    `login` functions
  `edit_and_check_password`
    `login` functions
  `rpc_prog`
    `portmapper` functions
  `pm_check_getport`
    `portmapper` functions
  `pm_activity`
    `portmapper` functions
  `pm_request`
    `portmapper` functions
  `pm_attempt`
    `portmapper` functions
  `report_weird`
    `weird` functions
  `report_weird_conn`
    `weird` functions
  `report_weird_orig`
    `weird` functions
  `open`
    Files
  `open_for_append`
    Files
  anonymous
    Expressions
  redefining
    Functions
  site-specific
    Site-specific functions
`g` format
  Predefined Functions
`garbage args` (RPC status code)
  `portmapper` functions
general Bro processing events
  General Processing Events
general scripting
  Predefined Functions
generic connection analysis
  Generic Connection Analysis
`GET` HTTP method
  `http` variables
`get_login_state` function
  Predefined Functions
`get_orig_seq` function
  Predefined Functions
`get_resp_seq` function
  Predefined Functions
`getenv` function
  Predefined Functions
GETPORT portmapper call
  The `portmapper` Analyzer
global scope
  of enumerations
    Enumerations
`global` variable declaration
  Scope
global variables
  Scope
  `interfaces`
    Live traffic
  `capture_filter`
    Flags
  `restrict_filter`
    Flags
  `interfaces`
    Flags
  `done_with_network`
    Expressions
`-h` flag
  Flags
half-finished connections
  Generic TCP connection events
handling signals
  General Processing Events
`HEAD` HTTP method
  `http` variables
headers
  truncated
    Events handled by `net_weird`
help message
  Flags
heuristics
  attacker-induced confusion
    `login` analyzer confusion
  confusion
    `login` analyzer confusion
  environment
    `login` analyzer confusion
  extracting username information
    The `login` Analyzer | `login` analyzer confusion
  missing login prompt
    `login` analyzer confusion
  missing username
    `login` analyzer confusion | `login` analyzer confusion
  multiple login prompts
    `login` analyzer confusion | `login` analyzer confusion
  multiple usernames
    `login` analyzer confusion
  type-ahead
    `login` analyzer confusion
  VMS
    `login` analyzer confusion | `login` analyzer confusion | `login` analyzer confusion
`\x` hex-digits hexadecimal escape
  String Constants
hf utility program
  no title
host order (vs. network order)
  Predefined Functions
`hostname`
  The `dns_mapping` record
  `dns_mapping` field
    The `dns_mapping` record
hostnames
  Address Constants
  mapping addresses to
    The hf utility
hosts
  excluding
    Filtering
  in a connection
    Connection summaries
`hot`
  The `connection` record
  `connection` field
    The `connection` record
hot /24 destination networks
  `hot` variables
hot /24 source networks
  `hot` variables
`hot` analyzer
  The `hot` Analyzer
`hot check_info` record
  `login` functions
hot connection
  analysis
    The `hot` Analyzer
  logging
    Connection functions
hot connections
  `login` functions | `login` functions
hot destination addresses
  `hot` variables
hot detection
  `hot` functions
hot source addresses
  `hot` variables
hot usernames
  The `hot-ids` Module
`hot-ids` module
  The `hot-ids` Module
`hot_dst_24nets` variable
  `hot` variables
`hot_dsts` variable
  `hot` variables
`hot_id check_info` record
  `login` functions
`hot_ident_exceptions` variable
  `ident` variables
`hot_ident_ids` variable
  `ident` variables
`hot_ids` variable
  The `hot-ids` Module
`hot_login` function
  `login` functions
`hot_login_ids` variable
  `login` variables
`hot_names` variable
  `finger` variables
`hot_src_24nets` variable
  `hot` variables
`hot_srcs` variable
  `hot` variables
`hot_ssh_orig_ports` variable
  `login` variables
`hot_telnet_orig_ports` variable
  `login` variables
`hot_terminal_types` variable
  `login` variables
`hr` (hours) interval unit
  Temporal Constants
HTTP
  analysis
    The `http` Analyzer
  log file
    `http` variables
  weird events
    Events handled by `conn_weird`
`http` analyzer
  The `http` Analyzer
HTTP methods
  `http` variables | `http` variables | `http` variables | `http` variables
  `GET`
    `http` variables
  `HEAD`
    `http` variables
  `POST`
    `http` variables
HTTP packets
  contents not being recorded
    Flags
`http` session summary file
  `http` variables
`http_request` event
  `http` event handlers
`HTTP_unknown_method` (``weird'' event)
  Events handled by `conn_weird`
`HTTP_version_mismatch` (``weird'' event)
  Events handled by `conn_weird`
HUP signal
  General Processing Events
`-i` flag
  Flags
ICMP
  checksum error
    Events handled by `conn_weird`
  connections
    Definitions of connections
  timeout
    Definitions of connections
  weird events
    Events handled by `conn_weird`
`id`
  The `connection` record | The `ftp_session_info` record
  `ftp_session_info` field
    The `ftp_session_info` record
ID of connection
  Connection functions | Connection functions
`id_string` function
  Connection functions
IDENT
  analysis
    The `ident` Analyzer
  weird events
    Events handled by `conn_weird_addl`
`ident` analyzer
  The `ident` Analyzer
`ident/` authentication annotation
  `ident` event handlers
`ident_error` event
  `ident` event handlers
`ident_reply` event
  `ident` event handlers
`ident_request` event
  `ident` event handlers
`ident_request_addendum` (``weird'' event)
  Events handled by `conn_weird_addl`
IEUser
  useless FTP username
    `ftp` variables
`if` keyword
  Statements
`if` statement
  Statements
implicit typing
  Typing
`in` operator
  Embedded Pattern Matching | Expressions | Expressions
in-order delivery
  The `analy` Analyzer
`"!in` negation of `in` operator
  Embedded Pattern Matching
`inappropriate_FIN` (``weird'' event)
  Events handled by `conn_weird`
inbound services
  fatal
    `hot` variables
  forbidden
    `hot` variables
`incompletely_captured_fragment` (``weird'' event)
  Events handled by `flow_weird`
inconsistent acknowledgment
  Additional handlers for ``weird''
inconsistent retransmission
  Events handled by `conn_weird` | Additional handlers for ``weird''
`inconsistent_option` event
  `login` event handlers
increment expressions
  Expressions
index
  of a table
    Tables
index expression
  Expressions
inetd.conf
  `hot` variables
inferring types
  Typing
information associated with a connection
  The `connection` record | Connection summaries
`ingreslock` popular backdoor
  `hot` variables
initialization event
  General Processing Events
initialization of variables
  Initialization
input
  analysis
    The `login` Analyzer
  editing
    `login` variables
`input_trouble` variable
  `login` variables
installing Bro
  Installing Bro
`int`
  see types, `int`
INT signal
  General Processing Events
integers
  network vs. host order
    Predefined Functions
`interfaces` global variable
  Live traffic | Flags
`interfaces` variable
  Predefined Variables
internal networks
  spoof detection
    `hot` variables
internal variables
  `ATTEMPT_INTERVAL`
    Generic TCP connection events
  `PARTIAL_CLOSE_INTERVAL`
    Generic TCP connection events
  `WATCHDOG_INTERVAL`
    Flags
`internally_truncated_header` (``weird'' event)
  Events handled by `net_weird`
Internet Relay Chat (IRC)
  attacker subpopulation
    `login` variables
`interval`
  see types, `interval`
`interval` maximum
  Predefined Functions
`interval` minimum
  Predefined Functions
interval units
  `usec`
    Temporal Constants
  `sec`
    Temporal Constants
  `min`
    Temporal Constants
  `hr`
    Temporal Constants
  `day`
    Temporal Constants
invocation
  function
    Expressions
invoking event handlers
  Event handlers
IP
  checksum error
    Events handled by `net_weird`
  fragments
    Events handled by `flow_weird`
  identification field
    The `analy` Analyzer
  weird events
    Events handled by `net_weird`
IPv4/IPv6 address constants
  Address Constants
IPv6 and lack of CIDR prefixes
  Net Type
IPv6 support
  Address Type
IRC
  `login` variables
`is not a TCP connection`
  Predefined Functions | Predefined Functions
`is_forbidden_id` function
  `login` functions
`is_ftp_data_conn` function
  `ftp` functions
`is_hot_id` function
  `login` functions
`is_local_addr` function
  Site-specific functions
`is_login_conn` function
  `login` functions
`is_tcp_port` function
  Predefined Functions
isascii
  Predefined Functions | Predefined Functions
islower
  Predefined Functions
isupper
  Predefined Functions
keystrokes
  analysis
    The `login` Analyzer
  editing
    `login` variables
keywords
  `print`
    Statements
  `log`
    Statements
  `event`
    Statements
  `if`
    Statements
  `else`
    Statements
  `for`
    Statements
  `next`
    Statements
  `break`
    Statements
  `return`
    Statements
  `add`
    Statements
  `delete`
    Statements
  `function`
    Expressions
  `schedule`
    Expressions
kiddies
  script
    `hot` variables
Land attack
  `hot` functions | Events generated by the
`Land_attack` (``weird'' event)
  Events generated by the
large BPF buffers
  Tuning BPF
`(` operator
  Expressions | Expressions
length
  of strings
    Predefined Functions
  of table or set
    Predefined Functions
`length` function
  Predefined Functions
length mismatch
  UDP
    Events handled by `conn_weird`
`length() requires a table/set argument`
  Predefined Functions
`length() takes exactly one argument`
  Predefined Functions
lex utility
  Pattern Constants
libpcap buffer size patch
  Tuning BPF
libpcap library
  Tuning BPF
libraries
  libpcap
    Tuning BPF
  libpcap
    Tuning BPF
line editing
  Predefined Functions
Linux
  compiling Bro under
    The Bro source code
  super exploit
    `login` variables
little endian
  Predefined Functions | The `analy` Analyzer
live traffic
  Statements | Predefined Functions
load
  shedding
    Predefined Functions
`loadmodule` exploit
  `login` variables
local addresses
  Site variables | Site variables | Site variables | Site-specific functions
  spoofing
    `hot` variables | `hot` variables | `hot` functions
`local` statement
  Statements
`local` variable declaration
  Scope
local variables
  Statements | Scope
`local_16_nets` variable
  Site variables
`local_24_nets` variable
  Site variables
`local_nets` variable
  Site variables
log file
  Predefined Variables | Predefined Functions | The `log` Module
  altering
    `login` variables
  connection summary (`red`)
    Connection functions
  FTP
    `ftp` variables
  HTTP
    `http` variables
  weird events
    The `weird` Module
`log` keyword
  Statements
`log` module
  The `log` Module
`log` statement
  Statements
`log_file_name` function
  Predefined Functions
`log_hook` function
  The `log` Module | The `log` Module | The `log` Module
`log_hook` predefined function
  Predefined Functions
`log_hot_conn` function
  Connection functions
`log_if_not_denied`
  The `ftp_session_info` record
  `ftp_session_info` field
    The `ftp_session_info` record
`log_if_not_unavail`
  The `ftp_session_info` record
  `ftp_session_info` field
    The `ftp_session_info` record
`log_it`
  The `ftp_session_info` record
  `ftp_session_info` field
    The `ftp_session_info` record
`LOG_NOTICE` syslog level
  Statements
logging
  connection
    Connection functions
  control of
    Predefined Functions
logical expression
  Expressions
logical negation
  Logical Operators
login analysis
  confusion
    `login` analyzer confusion
`login` analyzer
  The `login` Analyzer
login confusion states
  `login` analyzer confusion | `login` analyzer confusion | `login` analyzer confusion | `login` analyzer confusion | `login` analyzer confusion | `login` analyzer confusion | `login` analyzer confusion | `login` analyzer confusion | `login` analyzer confusion | `login` analyzer confusion | `login` analyzer confusion | `login` analyzer confusion
  `excessive_typeahead`
    `login` analyzer confusion
  `extra_repeat_text`
    `login` analyzer confusion
  `multiple_login_prompts`
    `login` analyzer confusion
  `multiple_USERs`
    `login` analyzer confusion
  `no_login_prompt`
    `login` analyzer confusion
  `no_username`
    `login` analyzer confusion
  `no_username2`
    `login` analyzer confusion
  `non_empty_multi_login`
    `login` analyzer confusion
  `possible_login_ploy`
    `login` analyzer confusion
  `repeat_without_username`
    `login` analyzer confusion
  `responder_environment`
    `login` analyzer confusion
  `username_with_embedded_repeat`
    `login` analyzer confusion
login prompts
  missing
    `login` analyzer confusion
  repeated
    `login` analyzer confusion | `login` analyzer confusion
login session
  The `login` Analyzer
  state
    Predefined Functions | Predefined Functions
`login_confused` event
  `login` event handlers
`login_confused_text` event
  `login` event handlers
`login_failure` event
  `login` event handlers
`login_failure_msgs` variable
  Predefined Variables | `login` variables
`login_input_line` event
  `login` event handlers
`login_non_failure_msgs` variable
  Predefined Variables | `login` variables
`login_output_line` event
  `login` event handlers
`login_prompts` variable
  Predefined Variables | `login` variables
`LOGIN_STATE_AUTHENTICATE` state of login connection
  Predefined Functions
`LOGIN_STATE_CONFUSED` state of login connection
  Predefined Functions
`LOGIN_STATE_LOGGED_IN` state of login connection
  Predefined Functions
`LOGIN_STATE_SKIP` state of login connection
  Predefined Functions
`login_success` event
  `login` event handlers
`login_success_msgs` variable
  Predefined Variables | `login` variables
`login_terminal` event
  `login` event handlers
`login_timeouts` variable
  Predefined Variables | `login` variables
ls utility
  `login` variables
lynx utility
  `login` variables
magic terminal types
  `login` variables
management
  of state
    Table Attributes
`mask_addr` function
  Predefined Functions
masking
  Predefined Functions | Predefined Functions
`max_count` function
  Predefined Functions
`max_double` function
  Predefined Functions
`max_interval` function
  Predefined Functions
`max_request_length` variable
  `finger` variables
`max_timer_expires` variable
  Predefined Variables
maximum
  Predefined Functions
Maximum Segment Lifetime (MSL)
  Events handled by `conn_weird`
maximums
  Predefined Functions | Predefined Functions | Predefined Functions
  `count`
    Predefined Functions
  `double`
    Predefined Functions
  `interval`
    Predefined Functions
membership expression
  Expressions
memory management
  Table Attributes
message
  `connection id is not a known connection`
    Predefined Functions
  `not exactly one edit character`
    Predefined Functions
  `precision specified for non-floating point format`
    Predefined Functions
  `ridiculous field width or precision`
    Predefined Functions
  `bad format`
    Predefined Functions
  `bad type for Date format`
    Predefined Functions
  `bad type for integer format`
    Predefined Functions
  `bad type for floating-point format`
    Predefined Functions
  `wrong number of fmt arguments`
    Predefined Functions
  `too many arguments for format`
    Predefined Functions
  `too few arguments for format`
    Predefined Functions
  `connection id is not a known login connection`
    Predefined Functions
  `is not a TCP connection`
    Predefined Functions
  `is not a TCP connection`
    Predefined Functions
  `length() takes exactly one argument`
    Predefined Functions
  `length() requires a table/set argument`
    Predefined Functions
  `bad second argument to mask_addr()`
    Predefined Functions
  `cannot create directory`
    Predefined Functions
  `connection id is not a known login connection`
    Predefined Functions
  `conversion of non-IPv4 address to net`
    Predefined Functions
  `connection id is not a known connection`
    Run-time errors for non-existing
  `string without NUL terminator`
    Run-time errors for strings
  `string with embedded NUL`
    Run-time errors for strings
`min` (minutes) interval unit
  Temporal Constants
`min_count` function
  Predefined Functions
`min_double` function
  Predefined Functions
`min_interval` function
  Predefined Functions
minimum
  Predefined Functions
minimums
  Predefined Functions | Predefined Functions | Predefined Functions
  `count`
    Predefined Functions
  `double`
    Predefined Functions
  `interval`
    Predefined Functions
`mismatch` (RPC status code)
  `portmapper` functions
missing login prompts
  `login` analyzer confusion
missing username
  `login` analyzer confusion | `login` analyzer confusion
mkdir failure
  run-time error
    Predefined Functions
`mkdir` function
  Predefined Functions
modifiability of variables
  Modifiability
modules
  `port-name`
    The `port-name` Module
  `mt`
    The `mt` Module
  `log`
    The `log` Module
  `active`
    The `active` Module
  `demux`
    The `demux` Module
  `dns`
    The `dns` Module
  `frag`
    The `frag` Module
  `hot-ids`
    The `hot-ids` Module
  `weird`
    The `weird` Module
  dns
    event handlers
      `dns` event handlers to `dns` event handlers
    variables
      `dns` variables to `dns` variables
MSL (Maximum Segment Lifetime)
  Events handled by `conn_weird`
`mt` module
  The `mt` Module
multi-dimensional table
  Declaring Tables
multiple login prompts
  `login` analyzer confusion | `login` analyzer confusion
multiple usernames
  `login` analyzer confusion
`multiple_HTTP_request_elements` (``weird'' event)
  Events handled by `conn_weird`
`multiple_login_prompts` (login confusion state)
  `login` analyzer confusion
`multiple_RPCs` (``weird'' event)
  Events handled by `conn_weird`
`multiple_USERs` (login confusion state)
  `login` analyzer confusion
multiplication
  numeric
    Arithmetic Operators
  temporal
    Temporal Multiplication
name
  of log file
    Predefined Functions
names
  case-sensitive
    Defining records
Napster
  tunneled over Telnet or Rlogin
    `login` event handlers
negation
  logical
    Logical Operators
  temporal
    Temporal Negation
negation expression
  Expressions
neighbor addresses
  Site variables | Site variables | Site variables
`neighbor_16_nets` variable
  Site variables
`neighbor_24_nets` variable
  Site variables
`neighbor_nets` variable
  Site variables
`net`
  see types, `net`
  constants
    Net Constants
  operators
    Net Operators
net type
  Net Type to Net Operators
`net_done` event
  General Processing Events
`net_stats` record
  General Processing Events | General Processing Events
`net_stats_update` event
  General Processing Events
`net_weird` event
  Events handled by `net_weird`
network cleanup event
  General Processing Events
Network File System (NFS)
  `portmapper` variables
network interfaces
  Live traffic | Flags | Predefined Variables
network order (vs. host order)
  Predefined Functions
network prefixes
  Net Type | Predefined Functions | Site variables | Site variables
network statistics
  General Processing Events
Network Virtual Terminal (NVT)
  `login` event handlers
`network_time` function
  Predefined Functions
networks
  hot destinations
    `hot` variables
  hot sources
    `hot` variables
`never_shut_down` variable
  `scan` variables
new connection
  Generic TCP connection events
`new_connection` event
  Generic TCP connection events
`\n` newline escape
  String Constants
`next` keyword
  Statements
`next` statement
  Statements
NFS (Network File System)
  `portmapper` variables
NFS traffic
  high volume fragments
    The `frag` Module
`NFS_services` variable
  `portmapper` variables
`NFS_world_servers` variable
  `portmapper` variables
no such connection
  run-time error
    Run-time errors for non-existing
`no_login_prompt` (login confusion state)
  `login` analyzer confusion
`no_username` (login confusion state)
  `login` analyzer confusion
`no_username2` (login confusion state)
  `login` analyzer confusion
non-blocking DNS lookups
  The Bro source code
non-existing connection
  fatal run-time error
    Predefined Functions
`non_ASCII_hosts` variable
  `login` variables
`non_backdoor_prompts` variable
  `login` variables
`non_empty_multi_login` (login confusion state)
  `login` analyzer confusion
`<none>` username
  `login` analyzer confusion
not a login connection
  run-time error
    Predefined Functions | Predefined Functions
not a TCP connection
  run-time error
    Predefined Functions | Predefined Functions
`not exactly one edit character`
  Predefined Functions
`"!in` negation of `in` operator
  Embedded Pattern Matching
`!` ``not'' operator
  Logical Operators
NT
  not supported
    Supported platforms
NUL
  Predefined Functions
`NUL_in_line` (``weird'' event)
  Events handled by `conn_weird`
NULL portmapper call
  The `portmapper` Analyzer
null statement
  Statements
NULs
  Events handled by `conn_weird`
  allowed in strings
    String Constants | Run-time errors for non-existing
  disallowed in certain function calls
    Run-time errors for non-existing
  terminating string constants
    String Constants
  termination
    Run-time errors for non-existing
  terminator missing
    run-time error
      Run-time errors for strings
`num_in_order` statistic
  The `analy` Analyzer
`num_OO` statistic
  The `analy` Analyzer
`num_pkts` statistic
  The `analy` Analyzer
`num_repl` statistic
  The `analy` Analyzer
`num_requests`
  The `ftp_session_info` record
  `ftp_session_info` field
    The `ftp_session_info` record
`num_rxmit` statistic
  The `analy` Analyzer
`num_rxmit_bytes` statistic
  The `analy` Analyzer
number of elements
  in table or set
    Predefined Functions
numeric types
  `count`
    Bro Types
  `int`
    Bro Types
  `double`
    Bro Types
`nuucp` username
  The `hot-ids` Module | `ident` variables
NVT (Network Virtual Terminal)
  `login` event handlers
NVT options
  authentication
    `login` event handlers | `login` event handlers
  bad
    `login` event handlers
  bad termination
    `login` event handlers
  encryption
    `login` event handlers
  inconsistent
    `login` event handlers
`-O` flag
  Flags
`\`octal-digits octal escape
  String Constants
off-line analysis
  Traffic traces | Flags | Predefined Functions | Connection functions
`ok` (RPC status code)
  `portmapper` functions
on-line analysis
  Live traffic | Flags | Predefined Variables | Predefined Functions | Connection functions
`open` function
  Files | Predefined Functions
`open_for_append` function
  Files | Predefined Functions
`open_log_file` function
  Predefined Functions
opening a file
  Predefined Functions | Predefined Functions
operator
  `&&` ``and''
    Logical Operators | Expressions
  `(` parenthesis
    Expressions | Expressions
  `!` ``not''
    Logical Operators
  `"|"|` ``or''
    Logical Operators | Expressions
  `)` parenthesis
    Expressions | Expressions
operators
  `+=`
    Filtering
  `+`
    Arithmetic Operators
  `-`
    Arithmetic Operators
  `*`
    Arithmetic Operators
  `/`
    Arithmetic Operators
  `+`
    Arithmetic Operators
  `-`
    Arithmetic Operators
  `-`
    Temporal Negation
  `+`
    Temporal Addition
  `-`
    Temporal Subtraction
  `*`
    Temporal Multiplication
  `/`
    Temporal Division
  `$`
    Accessing Fields Using ```$`''
  `++`
    Expressions
  `-`
    Expressions
  `!`
    Expressions
  `-`
    Expressions
  `+`
    Expressions
  `+`
    Expressions
  `-`
    Expressions
  `*`
    Expressions
  `/`
    Expressions
  `?`
    Expressions
  `:`
    Expressions
  `=`
    Expressions
  `(`
    Expressions
  `)`
    Expressions
  `[`
    Expressions
  `]`
    Expressions
  `in`
    Expressions
  `!in`
    Expressions
  `in`
    Expressions
  `!in`
    Expressions
  `[`
    Expressions
  `]`
    Expressions
  address
    Address Operators
  arithmetic
    Arithmetic Operators to Arithmetic Operators
    associativity
      Arithmetic Operators
    operand conversion
      Arithmetic Operators
    precedence
      Arithmetic Operators
  comparison
    Comparison Operators to Comparison Operators
    associativity
      Comparison Operators
    operand conversion
      Comparison Operators
    precedence
      Comparison Operators
  logical
    Logical Operators to Logical Operators
    associativity
      Logical Operators
    precedence
      Logical Operators
  net
    Net Operators
  pattern
    Pattern Operators
  ports
    Port Operators
  string
    String Operators
  temporal
    Temporal Operators
optimizer for policy script interpreter
  Flags
optimizing your system for Bro
  Tuning BPF
options
  Telnet
    The `login` Analyzer
`"|"|` ``or'' operator
  Logical Operators | Expressions
`orig`
  The `connection` record
`orig_h`
  The `connection` record
  `conn_id` field
    The `connection` record
`orig_p`
  The `connection` record
  `conn_id` field
    The `connection` record
`originator_RPC_reply` (``weird'' event)
  Events handled by `conn_weird`
`OTH` connection state
  Connection summaries
out-of-order delivery
  The `analy` Analyzer
`OutOfBox` username
  The `hot-ids` Module
`output_trouble` variable
  `login` variables
`-P` flag
  Flags | Flags | The `dns` Module
packet filter
  access
    Tuning BPF
  permissions
    Tuning BPF
packets
  control (SYN/FIN/RST)
    Flags | The `tcp` analyzer
  corrupted
    Events handled by `conn_weird` | Events handled by `net_weird`
  drops
    General Processing Events | Additional handlers for ``weird''
  recording
    Predefined Functions
  replication
    The `analy` Analyzer
  storms
    Events handled by `conn_weird`
  time
    Predefined Functions
`()`
  Expressions | Expressions
parenthesized expression
  Expressions
`parse_ftp_pasv` function
  Predefined Functions
`parse_ftp_port` function
  Predefined Functions
partial connections
  Generic TCP connection events
`PARTIAL_CLOSE_INTERVAL` internal variable
  Generic TCP connection events
`partial_connection` event
  Generic TCP connection events | `login` event handlers
`partial_finger_request` (``weird'' event)
  Events handled by `conn_weird`
`partial_ftp_request` (``weird'' event)
  Events handled by `conn_weird`
`partial_ident_request` (``weird'' event)
  Events handled by `conn_weird`
`partial_portmapper_request` (``weird'' event)
  Events handled by `conn_weird`
`partial_RPC` (``weird'' event)
  Events handled by `conn_weird`
partially closed connections
  Generic TCP connection events
passwd
  `http` variables
passwords
  guessing
    The `scan` Analyzer
  inadvertently exposed
    The `login` Analyzer
  sniffing
    The `login` Analyzer
`PATH_UTMP` sensitive pattern
  `login` variables
`pattern`
  see types, `pattern`
pattern matching
  Patterns
  embedded
    Embedded Pattern Matching
  exact
    Exact Pattern Matching
pattern matching expression
  Expressions
patterns
  Patterns to Embedded Pattern Matching
pending connections
  Generic TCP connection events
`pending_data_when_closed` (``weird'' event)
  Events handled by `conn_weird`
performance
  analysis tradeoffs
    Activating an Analyzer
  filtering
    Filtering
`pm_activity` function
  `portmapper` functions
`pm_attempt` function
  `portmapper` functions
`pm_attempt` portmapper attempt
  `portmapper` event handlers
`pm_attempt_callit` event
  `portmapper` event handlers
`pm_attempt_dump` event
  `portmapper` event handlers
`pm_attempt_getport` event
  `portmapper` event handlers
`pm_attempt_null` event
  `portmapper` event handlers
`pm_attempt_set` event
  `portmapper` event handlers
`pm_attempt_unset` event
  `portmapper` event handlers
`pm_bad_port` event
  `portmapper` event handlers
`pm_callit_request` portmapper call
  `portmapper` event handlers
`pm_check_getport` function
  `portmapper` functions
`pm_mapping` portmapper mapping record
  `portmapper` event handlers
`pm_port_request` portmapper request
  `portmapper` event handlers
`pm_request` function
  `portmapper` functions
`pm_request_callit` event
  `portmapper` event handlers
`pm_request_dump` event
  `portmapper` event handlers
`pm_request_getport` event
  `portmapper` event handlers
`pm_request_null` event
  `portmapper` event handlers
`pm_request_set` event
  `portmapper` event handlers
`pm_request_unset` event
  `portmapper` event handlers
policy/ policy directory
  Run-time environment
policy directories
  Run-time environment
policy script interpreter
  optimizer
    Flags
policy/local/ policy directory
  Run-time environment
polymorphic functions
  need for
    Predefined Functions | Predefined Functions | Events handled by `conn_weird_addl`
popular backdoors
  `hot` variables
  `ingreslock`
    `hot` variables
`port`
  see types, `port`
  ephemeral
    Connection functions
port scanning
  The `scan` Analyzer
port type
  Port Type to Port Operators
`port-name` module
  The `port-name` Module
`port_names` variable
  The `connection` record | Connection functions | The `port-name` Module
`portmapper` analyzer
  The `portmapper` Analyzer
portmapper attempts
  `portmapper` event handlers
  `pm_attempt`
    `portmapper` event handlers
portmapper calls
  `portmapper` event handlers
  CALLIT
    The `portmapper` Analyzer
  DUMP
    The `portmapper` Analyzer
  GETPORT
    The `portmapper` Analyzer
  NULL
    The `portmapper` Analyzer
  `pm_callit_request`
    `portmapper` event handlers
  SET
    The `portmapper` Analyzer
  UNSET
    The `portmapper` Analyzer
portmapper mapping records
  `portmapper` event handlers
  `pm_mapping`
    `portmapper` event handlers
portmapper requests
  `portmapper` event handlers
  `pm_port_request`
    `portmapper` event handlers
ports
  constants
    Port Constants
  operators
    Port Operators
  TCP
    Port Type
  TCP vs. UDP
    Predefined Functions
  UDP
    Port Type
positivation expression
  Expressions
possible future changes
  `timer` type
    Expressions
  breaking string constants across multiple lines
    String Constants
  constants for absolute times
    Temporal Constants
  use of `any` type for bypassing strong typing
    The `any` type
possible packet drop messages
  Additional handlers for ``weird''
  `ack above a hole`
    Additional handlers for ``weird''
`possible_login_ploy` (login confusion state)
  `login` analyzer confusion
`possible_port_scan_thresh` variable
  `scan` variables
`possible_split_routing` (``weird'' event)
  Events handled by `conn_weird`
`POST` HTTP method
  `http` variables
precision
  of formatted strings
    Predefined Functions
`precision specified for non-floating point format`
  Predefined Functions
predefined functions
  Predefined Functions to Functions for manipulating time
  `active_connection`
    Predefined Functions
  `active_file`
    Predefined Functions
  `add_interface`
    Predefined Functions
  `add_tcpdump_filter`
    Predefined Functions
  `log_hook`
    Predefined Functions
  `byte_len`
    Predefined Functions
  `cat`
    Predefined Functions
  `clean`
    Predefined Functions
  `close`
    Predefined Functions
  `connection_record`
    Predefined Functions
  `contains_string`
    Predefined Functions
  `current_time`
    Predefined Functions
  `discarder_check_icmp`
    Predefined Functions
  `discarder_check_ip`
    Predefined Functions
  `discarder_check_tcp`
    Predefined Functions
  `discarder_check_udp`
    Predefined Functions
  `edit`
    Predefined Functions
  `exit`
    Predefined Functions
  `flush_all`
    Predefined Functions
  `fmt`
    Predefined Functions
  `get_login_state`
    Predefined Functions
  `get_orig_seq`
    Predefined Functions
  `get_resp_seq`
    Predefined Functions
  `getenv`
    Predefined Functions
  `is_tcp_port`
    Predefined Functions
  `length`
    Predefined Functions
  `log_file_name`
    Predefined Functions
  `mask_addr`
    Predefined Functions
  `max_count`
    Predefined Functions
  `max_double`
    Predefined Functions
  `max_interval`
    Predefined Functions
  `min_count`
    Predefined Functions
  `min_double`
    Predefined Functions
  `min_interval`
    Predefined Functions
  `mkdir`
    Predefined Functions
  `network_time`
    Predefined Functions
  `open`
    Predefined Functions
  `open_for_append`
    Predefined Functions
  `open_log_file`
    Predefined Functions
  `parse_ftp_pasv`
    Predefined Functions
  `parse_ftp_port`
    Predefined Functions
  `reading_live_traffic`
    Predefined Functions
  `set_buf`
    Predefined Functions
  `set_contents_file`
    Predefined Functions
  `set_login_state`
    Predefined Functions
  `set_record_packets`
    Predefined Functions
  `skip_further_processing`
    Predefined Functions
  `sub_bytes`
    Predefined Functions
  `system`
    Predefined Functions
  `to_lower`
    Predefined Functions
  `to_net`
    Predefined Functions
  `to_upper`
    Predefined Functions
predefined variables
  Predefined Variables to Predefined Variables
  `bro_log_file`
    Predefined Variables
  `capture_filter`
    Predefined Variables
  `direct_login_prompts`
    Predefined Variables
  `discarder_maxlen`
    Predefined Variables
  `done_with_network`
    Predefined Variables
  `interfaces`
    Predefined Variables
  `login_failure_msgs`
    Predefined Variables
  `login_non_failure_msgs`
    Predefined Variables
  `login_prompts`
    Predefined Variables
  `login_success_msgs`
    Predefined Variables
  `login_timeouts`
    Predefined Variables
  `max_timer_expires`
    Predefined Variables
  `restrict_filter`
    Predefined Variables
  `skip_authentication`
    Predefined Variables
prefixes
  Flags | Run-time environment
  network
    Net Type | Predefined Functions | Site variables | Site variables
`premature_connection_reuse` (``weird'' event)
  Events handled by `conn_weird`
priming Bro's private caches (DNS, regular expression)
  Flags
`print` keyword
  Statements
`print` statement
  Statements
`print-filter` analyzer
  Filtering | Filtering | Filtering
printf
  Predefined Functions
processing
  avoiding
    Predefined Functions
`prog unavail` (RPC status code)
  `portmapper` functions
programs
  hf
    no title
  cf
    no title
`-r` flag
  Flags
reactive firewall
  `scan` variables | `scan` functions
`&read_expire` attribute
  Table Attributes
reading `tcpdump` files
  Flags
`reading_live_traffic` function
  Predefined Functions
`record`
  see types, `record`
  `ftp_port`
    Predefined Functions
  `ftp_port`
    Predefined Functions
  `connection`
    The `connection` record
record constructor expression
  Expressions
record field access expression
  Expressions
record field test expression
  Expressions
`record_connection` function
  Connection functions
recorded traffic
  Predefined Functions
recording connections
  Connection functions
recording packets
  Predefined Functions
records
  Records to Record Assignment | Predefined Functions | Predefined Functions | General Processing Events | General Processing Events | The `connection` record | The `connection` record | The `connection` record | The `connection` record | The `connection` record | The `connection` record | The `connection` record | The `connection` record | The `connection` record | The `connection` record | The `connection` record | Connection summaries | no title | The `dns_mapping` record | The `dns_mapping` record | no title | The `ftp_session_info` record | `login` functions
  assignment
    Record Assignment to Record Assignment
  `check_info`
    `login` functions
  `conn_id`
    The `connection` record | The `connection` record | The `connection` record
  `connection`
    The `connection` record | The `connection` record | The `connection` record | The `connection` record | The `connection` record
  `dns_mapping`
    no title | The `dns_mapping` record | The `dns_mapping` record
  `endpoint`
    The `connection` record | The `connection` record | The `connection` record | Connection summaries
  field attributes
    Record Assignment
  fields
    Records
    accessing
      Accessing Fields Using ```$`''
    legal names
      Defining records
  `ftp_port`
    Predefined Functions | Predefined Functions
  `ftp_session_info`
    no title | The `ftp_session_info` record
  `net_stats`
    General Processing Events | General Processing Events
`red` connection summary file
  Connection summaries | Connection summaries
`&redef` attribute
  Refinement
redefining functions
  Functions
redefining variables
  Refinement
refinement
  Refinement
regular expressions
  Bro's private cache
    Flags
  compiling
    Flags
`REJ` connection state
  Connection summaries
rejected connections
  Generic TCP connection events
relational expression
  Expressions
relationals
  address
    Address Type
  net
    Net Operators
  numeric
    Comparison Operators
  string
    String Operators
  temporal
    Temporal Relationals
relative time
  Temporal Types
remote procedure call (RPC)
  The `portmapper` Analyzer
repeat text
  `login` analyzer confusion | `login` analyzer confusion
repeat text (VMS)
  `login` analyzer confusion
`repeat_without_username` (login confusion state)
  `login` analyzer confusion
`repeated_SYN_reply_wo_ack` (``weird'' event)
  Events handled by `conn_weird`
`repeated_SYN_with_ack` (``weird'' event)
  Events handled by `conn_weird`
replication of packets
  The `analy` Analyzer
`report_accounts_tried` variable
  `scan` variables
`report_outbound_peer_scan` variable
  `scan` variables
`report_peer_scan` variable
  `scan` variables
`report_remote_accounts_tried` variable
  `scan` variables
`report_weird` function
  `weird` functions
`report_weird_conn` function
  `weird` functions
`report_weird_orig` function
  `weird` functions
`req_addr`
  The `dns_mapping` record
  `dns_mapping` field
    The `dns_mapping` record
`req_host`
  The `dns_mapping` record
  `dns_mapping` field
    The `dns_mapping` record
`request`
  The `ftp_session_info` record
  `ftp_session_info` field
    The `ftp_session_info` record
`request_t`
  The `ftp_session_info` record
  `ftp_session_info` field
    The `ftp_session_info` record
reserved multicast addresss
  `portmapper` variables
  `sun-rpc.mcast.net`
    `portmapper` variables
reset connections
  Generic TCP connection events
`resp`
  The `connection` record
`resp_h`
  The `connection` record
  `conn_id` field
    The `connection` record
`resp_p`
  The `connection` record
  `conn_id` field
    The `connection` record
`responder_environment` (login confusion state)
  `login` analyzer confusion
`responder_RPC_call` (``weird'' event)
  Events handled by `conn_weird`
`restrict_filter` global variable
  Flags
`restrict_filter` variable
  Predefined Variables | Filtering to Filtering
restricting traffic
  Filtering
retransmission
  inconsistent
    Events handled by `conn_weird` | Additional handlers for ``weird''
`return` keyword
  Statements
`return` statement
  Statements
`rewt` username
  The `hot-ids` Module | `login` variables
`rexmit_inconsistency` event
  Additional handlers for ``weird''
`.rhosts`
  `ftp` variables | The `login` Analyzer | `login` analyzer confusion | `login` variables | `login` event handlers
`ridiculous field width or precision`
  Predefined Functions
`)` operator
  Expressions | Expressions
`RLIMIT_NOFILE` a
  Files
Rlogin
  session state
    Predefined Functions | Predefined Functions
  sessions
    The `login` Analyzer
  weird events
    Events handled by `conn_weird`
`rlogin_id_okay_if_no_password_exposed` variable
  `login` variables
`rlogin_text_after_rejected` (``weird'' event)
  Events handled by `conn_weird`
root
  backdoors
    `login` variables
  Bro not running as
    Tuning BPF
  setuid
    `login` variables
`router_prompts` variable
  `login` variables
routing
  split
    Events handled by `conn_weird`
RPC (Remote Procedure Call)
  The `portmapper` Analyzer
  reserved multicast address
    `portmapper` variables
  weird events
    Events handled by `conn_weird`
RPC status codes
  `portmapper` functions | `portmapper` functions | `portmapper` functions | `portmapper` functions | `portmapper` functions | `portmapper` functions | `portmapper` functions | `portmapper` functions
  `auth error`
    `portmapper` functions
  `garbage args`
    `portmapper` functions
  `mismatch`
    `portmapper` functions
  `ok`
    `portmapper` functions
  `prog unavail`
    `portmapper` functions
  `system err`
    `portmapper` functions
  `timeout`
    `portmapper` functions
  `unknown`
    `portmapper` functions
`RPC_dump_okay` variable
  `portmapper` variables
`RPC_okay` variable
  `portmapper` variables
`RPC_okay_nets` variable
  `portmapper` variables
`RPC_okay_services` variable
  `portmapper` variables
`rpc_prog` function
  `portmapper` functions
`rpc_programs` variable
  `portmapper` variables
`RPC_rexmit_inconsistency` (``weird'' event)
  Events handled by `conn_weird`
RST control packet
  Flags | The `tcp` analyzer
RST termination
  causing undetermined connection size
    `ftp` variables
`RST_storm` (``weird'' event)
  Events handled by `conn_weird`
`RST_with_data` (``weird'' event)
  Events handled by `conn_weird`
`RSTO` connection state
  Connection summaries
`RSTOS0` connection state
  Connection summaries
`RSTR` connection state
  Connection summaries
`RSTRH` connection state
  Connection summaries
run-time error
  bad address mask
    Predefined Functions
  bad fmt date argument
    Predefined Functions
  bad fmt editing character
    Predefined Functions
  bad fmt field width
    Predefined Functions
  bad fmt floating-point argument
    Predefined Functions
  bad fmt format specifier
    Predefined Functions
  bad fmt integer argument
    Predefined Functions
  bad fmt precision
    Predefined Functions
  bad length argument (not a table or set)
    Predefined Functions
  can't open
    Run-time environment
  converting an IPv6 address to net
    Predefined Functions
  embedded NUL
    Run-time errors for strings
  mkdir failure
    Predefined Functions
  no such connection
    Run-time errors for non-existing
  non-existing connection
    Predefined Functions
  not a login connection
    Predefined Functions | Predefined Functions
  not a TCP connection
    Predefined Functions | Predefined Functions
  NULs
    terminator missing
      Run-time errors for strings
  watchdog timer expired
    Flags
  wrong number of fmt arguments
    Predefined Functions
  wrong number of length arguments
    Predefined Functions
running Bro
  Running Bro
running outside scripts or executables
  Predefined Functions
`S0` connection state
  Connection summaries
`S1` connection state
  Connection summaries
`S2` connection state
  Connection summaries
`S3` connection state
  Connection summaries
`same_local_net_is_spoof` variable
  `hot` variables
save file
  control over what's recorded
    Predefined Functions
  reading
    Flags
  writing
    Flags
scalars
  Declaring Tables
`scan` analyzer
  The `scan` Analyzer
scan detection
  The `scan` Analyzer to `scan` event handlers
scanning
  address
    The `scan` Analyzer
  port
    The `scan` Analyzer
  shutting down
    `scan` variables | `scan` functions
  stealth
    Generic TCP connection events | `hot` functions | `scan` functions | Events handled by `conn_weird` | Events handled by `conn_weird`
`schedule` keyword
  Expressions
scheduling events
  Expressions
scoping of variables
  Scope
script kiddies
  `hot` variables
scripting
  general
    Predefined Functions
scripts
  running
    Predefined Functions
  standard
    Analyzers and Events to The `interconn` Analyzer
search path
  Run-time environment
searching for strings
  Patterns
`sec` (seconds) interval unit
  Temporal Constants
semi-colon statement termination
  Statements
sensitive /24 destination networks
  `hot` variables
sensitive /24 source networks
  `hot` variables
sensitive destination addresses
  `hot` variables
sensitive filenames
  `ftp` variables | `login` variables
  `eggdrop`
    `ftp` variables
sensitive information
  inadvertently exposed
    The `login` Analyzer
sensitive login inputs
  `login` variables
  `eggdrop`
    `login` variables
sensitive patterns
  `login` variables
  `PATH_UTMP`
    `login` variables
sensitive POST URIs
  `http` variables
  `wwwroot`
    `http` variables
sensitive services
  confused with ephemeral ports
    `hot` variables
sensitive source addresses
  `hot` variables
sensitive usernames
  The `hot-ids` Module
`sensitive_post_URIs` variable
  `http` variables
`sensitive_URIs` variable
  `http` variables
sensitivity associated with a connection
  The `connection` record
sequence numbers
  connection originator
    Predefined Functions
  connection responder
    Predefined Functions
`service`
  The `connection` record
  `connection` field
    The `connection` record
service associated with a connection
  The `connection` record | Connection summaries | Connection functions | Connection functions
`service_name` function
  Connection functions
services
  allowable
    `hot` variables
  allowed to a particular host
    `hot` variables
  allowed to particular host pairs
    `hot` variables
  fatal if inbound
    `hot` variables
  forbidden
    `hot` variables
  forbidden if attempted
    `hot` variables
  forbidden if inbound
    `hot` variables
`set`
  see types, `set`
SET portmapper call
  The `portmapper` Analyzer
set size
  Predefined Functions
set type
  Sets to Sets
`set_buf` function
  Predefined Functions
`set_contents_file` function
  Predefined Functions
`set_login_state` function
  Predefined Functions
`set_record_packets` function
  Predefined Functions
`setrlimit` system calls
  Files
setuid root
  `login` variables
`SF` connection state
  Connection summaries
`sgiweb` username
  The `hot-ids` Module
sh
  Predefined Functions
`SH` connection state
  Connection summaries
shadow
  `http` variables
shadowing
  Filtering
shallow copy
  Record Assignment | Table Assignment
shedding load
  Predefined Functions
shell escape
  Predefined Functions
shell scripts
  drop-connectivity
    `scan` functions
short-circuit `&&` ``and'' operator
  Logical Operators | Expressions
short-circuit `"|"|` ``or'' operator
  Logical Operators | Expressions
`SHR` connection state
  Connection summaries
`shut_down_all_scans` variable
  `scan` variables
`shut_down_scans` variable
  `scan` variables
`shut_down_thresh` variable
  `scan` variables
shutting down scans
  `scan` variables | `scan` functions
SIGHUP
  General Processing Events
SIGINT
  General Processing Events
signal handling
  General Processing Events
SIGTERM
  General Processing Events
simultaneous open
  Events handled by `conn_weird`
`simultaneous_open` (``weird'' event)
  Events handled by `conn_weird`
site addresses
  Site-specific functions
`site` analyzer
  Site-specific information
site-specific
  functions
    Site-specific functions to Site-specific functions
  information
    Site-specific information
  variables
    Site variables to Site variables
`size`
  The `connection` record
  `endpoint` field
    The `connection` record
  of table or set
    Predefined Functions
size of connection
  Connection summaries | Connection functions
`skip_accounts_tried` variable
  `scan` variables
`skip_authentication` variable
  Predefined Variables | `login` variables
`skip_further_processing` function
  Predefined Functions
`skip_logins_to` variable
  `login` variables
`skip_outbound_services` variable
  `scan` variables
`skip_scan_nets_24` variable
  `scan` variables
`skip_scan_sources` variable
  `scan` variables
`skip_unexpected` variable
  `ftp` variables
`skip_unexpected_net` variable
  `ftp` variables
`(skipped)` authentication annotation
  `login` event handlers
slow startup due to compiling regular expressions
  Flags
`smashdu.c` exploit tool
  `login` variables
smurf attacks
  `login` variables
sniffer logs
  `login` variables
sniffing
  The `login` Analyzer
source code
  for Bro
    The Bro source code
split routing
  Events handled by `conn_weird`
`spontaneous_FIN` (``weird'' event)
  Events handled by `conn_weird`
`spontaneous_RST` (``weird'' event)
  Events handled by `conn_weird`
spoofing
  allowable services
    `hot` variables
  detection
    `hot` variables | `hot` functions
spook detection
  `hot` variables
sprintf
  Predefined Functions
standard scripts
  Analyzers and Events to The `interconn` Analyzer
start time of a connection
  The `connection` record | Connection summaries
`start_time`
  The `connection` record
  `connection` field
    The `connection` record
startup
  event
    General Processing Events
  transients
    Events handled by `conn_weird`
startup slow due to compiling regular expressions
  Flags
`state`
  The `connection` record
  `endpoint` field
    The `connection` record
  of a Telnet/Rlogin session
    Predefined Functions | Predefined Functions
state management
  Table Attributes
state of connection
  Connection summaries | Connection functions
state of login connections
  Predefined Functions | Predefined Functions | Predefined Functions | Predefined Functions
  `LOGIN_STATE_AUTHENTICATE`
    Predefined Functions
  `LOGIN_STATE_CONFUSED`
    Predefined Functions
  `LOGIN_STATE_LOGGED_IN`
    Predefined Functions
  `LOGIN_STATE_SKIP`
    Predefined Functions
statements
  Statements to Statements
  expression
    Statements
  `print`
    Statements
  `log`
    Statements
  `event`
    Statements
  `if`
    Statements
  `for`
    Statements
  `next`
    Statements
  `break`
    Statements
  `return`
    Statements
  `add`
    Statements
  `delete`
    Statements
  compound
    Statements
  null
    Statements
  `local`
    Statements
  `const`
    Statements
  multi-line
    Statements
  semi-colon termination
    Statements
static typing
  Bro Types
statistical analysis
  The `analy` Analyzer
statistics
  The `analy` Analyzer | The `analy` Analyzer | The `analy` Analyzer | The `analy` Analyzer | The `analy` Analyzer | The `analy` Analyzer | The `analy` Analyzer
  `endian_type`
    The `analy` Analyzer
  `num_in_order`
    The `analy` Analyzer
  `num_OO`
    The `analy` Analyzer
  `num_pkts`
    The `analy` Analyzer
  `num_repl`
    The `analy` Analyzer
  `num_rxmit`
    The `analy` Analyzer
  `num_rxmit_bytes`
    The `analy` Analyzer
stderr
  Predefined Variables | Predefined Functions | The `log` Module
stdout
  Statements | Predefined Functions
stealth scans
  Generic TCP connection events | `hot` functions | `scan` functions | Events handled by `conn_weird` | Events handled by `conn_weird`
storms
  Events handled by `conn_weird`
strftime
  Predefined Functions
`string`
  see types, `string`
  extraction
    Predefined Functions
  formatting
    Predefined Functions
string constants
  NUL terminated
    String Constants
`string with embedded NUL`
  Run-time errors for strings
`string without NUL terminator`
  Run-time errors for strings
`"<string-with-NUL>"` error value
  Run-time errors for strings
strings
  Strings to String Operators
  cleaned up
    Predefined Functions
  concatenation
    Predefined Functions
  length
    Predefined Functions
  termination with NULs
    Run-time errors for non-existing
strlen
  Predefined Functions
strstr
  Predefined Functions
sub-tables
  lack of
    Accessing Tables
`sub_bytes` function
  Predefined Functions
subnets
  Net Type | Predefined Functions | Predefined Functions | Site variables | Site variables
substrings
  Predefined Functions
subtraction
  numeric
    Arithmetic Operators
  temporal
    Temporal Subtraction
`sun-rpc.mcast.net` reserved multicast address
  `portmapper` variables
`suppress_pm_log` variable
  `portmapper` variables
SYN control packet
  Flags | The `tcp` analyzer
`SYN_after_close` (``weird'' event)
  Events handled by `conn_weird`
`SYN_after_partial` (``weird'' event)
  Events handled by `conn_weird`
`SYN_after_reset` (``weird'' event)
  Events handled by `conn_weird`
`SYN_inside_connection` (``weird'' event)
  Events handled by `conn_weird`
`SYN_seq_jump` (``weird'' event)
  Events handled by `conn_weird`
`SYN_with_data` (``weird'' event)
  Events handled by `conn_weird`
syslog
  Statements
syslog levels
  Statements
  `LOG_NOTICE`
    Statements
system callss
  Files
  `setrlimit`
    Files
system configuration
  Tuning BPF
`system err` (RPC status code)
  `portmapper` functions
`system` function
  Predefined Functions
T/TCP
  Events handled by `conn_weird`
`\t` tab escape
  String Constants
`table`
  see types, `table`
table size
  Predefined Functions
tables
  Tables to Deleting Table Elements
  clearing entries
    Table Assignment
TCP
  analysis
    The `tcp` analyzer
  checksum error
    Events handled by `conn_weird`
  Christmas packet
    Events handled by `conn_weird`
  connections
    Definitions of connections
  corrupted header
    Events handled by `net_weird`
  events
    Generic TCP connection events
  fragments
    The `frag` Module
  transaction
    Events handled by `conn_weird`
  weird events
    Events handled by `conn_weird`
`tcp` analyzer
  no title
TCP control packets (SYN/FIN/RST)
  Flags | The `tcp` analyzer
TCP vs. UDP ports
  Predefined Functions
TCP Wrappers
  reset vs. rejected connections
    Generic TCP connection events
TCP-specific connection events
  Generic TCP connection events
`TCP_christmas` (``weird'' event)
  Events handled by `conn_weird`
`tcpdump`
  Tuning BPF | Running Bro on network | Flags | Flags | Flags | Flags | Filtering | Filtering | Filtering
  bugs
    Filtering
  filters
    Flags | Filtering
  merging save files
    Flags
  reading save files
    Running Bro on network | Flags
  running concurrently with Bro
    Tuning BPF
  shadow
    Filtering
  turning off optimization
    Filtering
  writing save files
    Flags
Telnet
  options
    The `login` Analyzer
    authentication
      `login` event handlers | `login` event handlers
    bad
      `login` event handlers
    bad termination
      `login` event handlers
    encryption
      `login` event handlers
    environment
      `login` analyzer confusion
    inconsistent
      `login` event handlers
  session state
    Predefined Functions | Predefined Functions
  sessions
    The `login` Analyzer
temporal
  addition
    Temporal Addition
  constants
    Temporal Constants
  division
    Temporal Division
  multiplication
    Temporal Multiplication
  negation
    Temporal Negation
  relationals
    Temporal Relationals
  subtraction
    Temporal Subtraction
  types
    Temporal Types
TERM signal
  General Processing Events
terminal type backdoors
  `login` variables
  `VT666`
    `login` variables
`terminate_connection` function
  Connection functions
`terminate_successful_inbound_service` variable
  `hot` variables
terminating connections forcibly
  Connection functions
termination event
  General Processing Events | General Processing Events
text
  formatting
    Predefined Functions
TFreak
  `login` variables
`time`
  see types, `time` | Temporal Types to Temporal Relationals
  clock
    Predefined Functions | Predefined Functions
  packet
    Predefined Functions
`timeout` (RPC status code)
  `portmapper` functions
timer expiration
  Expressions | Predefined Variables
timers
  Expressions
timestamps
  mapping to readable form
    The cf utility
`to_lower` function
  Predefined Functions
`to_net` function
  Predefined Functions
`to_upper` function
  Predefined Functions
tolower
  Predefined Functions
`too few arguments for format`
  Predefined Functions
`too many arguments for format`
  Predefined Functions
toupper
  Predefined Functions
trace file
  control over what's recorded
    Predefined Functions
  reading
    Flags
  writing
    Flags
traffic
  live vs. recorded
    Statements | Predefined Functions
  restricting
    Filtering
transaction TCP
  Events handled by `conn_weird`
transients
  startup
    Events handled by `conn_weird`
trojaning
  `login` variables
truncated headers
  Events handled by `net_weird`
`truncated_header` (``weird'' event)
  Events handled by `net_weird`
`truncated_IP` (``weird'' event)
  Events handled by `net_weird`
tunneling
  `login` event handlers
type casting
  not provided in Bro
    The `any` type
type inference
  Typing
type-ahead
  maximum allowed
    `login` analyzer confusion
types
  `bool`
    Bro Types
  numeric
    Bro Types
  `count`
    Bro Types
  `int`
    Bro Types
  `double`
    Bro Types
  enumeration
    Bro Types
  `enum`
    Bro Types
  `string`
    Bro Types
  `pattern`
    Bro Types
  temporal
    Bro Types
  `time`
    Bro Types
  `interval`
    Bro Types
  `port`
    Bro Types
  `addr`
    Bro Types
  `net`
    Bro Types
  `record`
    Bro Types
  `table`
    Bro Types
  `set`
    Bro Types
  `file`
    Bro Types
  `function`
    Bro Types
  `event`
    Bro Types
  `bool`
    Logical Operators
  `count`
    Numeric Types
  `int`
    Numeric Types
  `double`
    Numeric Types
  numeric
    Numeric Types
  numeric
    to Comparison Operators
  `enum`
    Enumerations
  `string`
    Strings
  `pattern`
    Patterns
  `time`
    Temporal Types
  `interval`
    Temporal Types
  conversion
    Type Conversions to Type Conversions
    automatic
      Type Conversions
  numeric
    `bool` not numeric
      Mixing Numeric Types
    intermixing
      Mixing Numeric Types
  overview
    Bro Types
types, need fors
  The `connection` record
  `union`
    The `connection` record
typing
  static
    Bro Types
typing of variables
  Typing
UDP
  analysis
    The `udp` analyzer
  checksum error
    Events handled by `conn_weird`
  ``connections''
    Definitions of connections
  fragments
    The `frag` Module
  length mismatch
    Events handled by `conn_weird`
  timeout
    Definitions of connections
  weird events
    Events handled by `conn_weird`
`udp` analyzer
  no title
`UDP_datagram_length_mismatch` (``weird'' event)
  Events handled by `conn_weird`
`udp_reply` event
  The `udp` analyzer
`udp_request` event
  The `udp` analyzer
unanalyzed data
  Events handled by `conn_weird`
undirectional analysis
  Events handled by `conn_weird`
union type
  need for
    Predefined Functions
`union` types, need for
  The `connection` record
Unix analysis
  The `login` Analyzer
Unix support
  Supported platforms
Unix timestamps
  The cf utility
`unknown` (RPC status code)
  `portmapper` functions
`unpaired_RPC_response` (``weird'' event)
  Events handled by `conn_weird`
UNSET portmapper call
  The `portmapper` Analyzer
`unsolicited_SYN_response` (``weird'' event)
  Events handled by `conn_weird`
unusual events
  The `weird` Module to Additional handlers for ``weird''
  prevalence in actual network traffic
    The `weird` Module
usage message
  Flags
`usec` (microseconds) interval unit
  Temporal Constants
`user`
  The `ftp_session_info` record
  `ftp_session_info` field
    The `ftp_session_info` record
`$USER` environment variable
  `login` analyzer confusion
user keystrokes
  analysis
    The `login` Analyzer
  editing
    `login` variables
\tt Username: (VMS login prompt)
  `login` analyzer confusion
`username_with_embedded_repeat` (login confusion state)
  `login` analyzer confusion
usernames
  The `hot-ids` Module | The `hot-ids` Module | The `hot-ids` Module | The `hot-ids` Module | The `hot-ids` Module | The `hot-ids` Module | The `hot-ids` Module | The `hot-ids` Module | `ident` variables | `ident` variables | `ident` variables | `login` variables
  `4Dgifts`
    The `hot-ids` Module
  `daemon`
    The `hot-ids` Module | `ident` variables
  extracting
    The `login` Analyzer | `login` analyzer confusion
  `EZsetup`
    The `hot-ids` Module
  missing
    `login` analyzer confusion | `login` analyzer confusion
  `<none>`
    `login` analyzer confusion
  `nuucp`
    The `hot-ids` Module | `ident` variables
  `OutOfBox`
    The `hot-ids` Module
  repeated
    `login` analyzer confusion
  `rewt`
    The `hot-ids` Module | `login` variables
  sensitive
    The `hot-ids` Module
  `sgiweb`
    The `hot-ids` Module
  `uucp`
    The `hot-ids` Module | `ident` variables
/usr/local/lib/bro/ policy directory
  Run-time environment
utilities
  fetch
    `login` variables
  flex
    Pattern Constants
  lex
    Pattern Constants
  ls
    `login` variables
  lynx
    `login` variables
utility programs
  hf
    no title
  cf
    no title
`uucp` username
  The `hot-ids` Module | `ident` variables
`-v` flag
  Flags
`valid`
  The `dns_mapping` record
  `dns_mapping` field
    The `dns_mapping` record
values
  overview
    Overview
vantage point
  Events handled by `conn_weird`
variable declarations
  Scope | Scope | Modifiability
  `const`
    Modifiability
  `global`
    Scope
  `local`
    Scope
variable expression
  Expressions
variables
  `bro_log_file`
    Predefined Variables
  `capture_filter`
    Predefined Variables
  `direct_login_prompts`
    Predefined Variables
  `discarder_maxlen`
    Predefined Variables
  `done_with_network`
    Predefined Variables
  `interfaces`
    Predefined Variables
  `login_failure_msgs`
    Predefined Variables
  `login_non_failure_msgs`
    Predefined Variables
  `login_prompts`
    Predefined Variables
  `login_success_msgs`
    Predefined Variables
  `login_timeouts`
    Predefined Variables
  `max_timer_expires`
    Predefined Variables
  `restrict_filter`
    Predefined Variables
  `skip_authentication`
    Predefined Variables
  `capture_filter`
    Filtering
  `restrict_filter`
    Filtering
  `restrict_filter`
    to Filtering
  `capture_filter`
    to Filtering
  `port_names`
    The `connection` record
  `port_names`
    Connection functions
  `local_nets`
    Site variables
  `local_16_nets`
    Site variables
  `local_24_nets`
    Site variables
  `neighbor_nets`
    Site variables
  `neighbor_16_nets`
    Site variables
  `neighbor_24_nets`
    Site variables
  `same_local_net_is_spoof`
    `hot` variables
  `allow_spoof_services`
    `hot` variables
  `allow_pairs`
    `hot` variables
  `allow_16_net_pairs`
    `hot` variables
  `hot_srcs`
    `hot` variables
  `hot_dsts`
    `hot` variables
  `hot_src_24nets`
    `hot` variables
  `hot_dst_24nets`
    `hot` variables
  `allow_services`
    `hot` variables
  `allow_services_to`
    `hot` variables
  `allow_services_pairs`
    `hot` variables
  `flag_successful_service`
    `hot` variables
  `flag_successful_inbound_service`
    `hot` variables
  `terminate_successful_inbound_service`
    `hot` variables
  `flag_rejected_service`
    `hot` variables
  `report_peer_scan`
    `scan` variables
  `report_outbound_peer_scan`
    `scan` variables
  `possible_port_scan_thresh`
    `scan` variables
  `report_accounts_tried`
    `scan` variables
  `report_remote_accounts_tried`
    `scan` variables
  `skip_accounts_tried`
    `scan` variables
  `skip_outbound_services`
    `scan` variables
  `addl_web`
    `scan` variables
  `skip_scan_sources`
    `scan` variables
  `skip_scan_nets_24`
    `scan` variables
  `can_drop_connectivity`
    `scan` variables
  `shut_down_scans`
    `scan` variables
  `shut_down_all_scans`
    `scan` variables
  `shut_down_thresh`
    `scan` variables
  `never_shut_down`
    `scan` variables
  `port_names`
    The `port-name` Module
  `bro_log_file`
    The `log` Module
  `active_conn`
    The `active` Module
  `dns_interesting_changes`
    `dns` variables
  `hot_names`
    `finger` variables
  `max_request_length`
    `finger` variables
  `forbidden_ids`
    The `hot-ids` Module
  `forbidden_ids_if_no_password`
    The `hot-ids` Module
  `forbidden_id_patterns`
    The `hot-ids` Module
  `always_hot_ids`
    The `hot-ids` Module
  `hot_ids`
    The `hot-ids` Module
  `ftp_guest_ids`
    `ftp` variables
  `ftp_skip_hot`
    `ftp` variables
  `ftp_hot_files`
    `ftp` variables
  `ftp_not_actually_hot_files`
    `ftp` variables
  `ftp_hot_guest_files`
    `ftp` variables
  `skip_unexpected`
    `ftp` variables
  `skip_unexpected_net`
    `ftp` variables
  `sensitive_URIs`
    `http` variables
  `sensitive_post_URIs`
    `http` variables
  `hot_ident_ids`
    `ident` variables
  `hot_ident_exceptions`
    `ident` variables
  `input_trouble`
    `login` variables
  `edited_input_trouble`
    `login` variables
  `output_trouble`
    `login` variables
  `backdoor_prompts`
    `login` variables
  `non_backdoor_prompts`
    `login` variables
  `hot_terminal_types`
    `login` variables
  `hot_telnet_orig_ports`
    `login` variables
  `hot_ssh_orig_ports`
    `login` variables
  `skip_authentication`
    `login` variables
  `direct_login_prompts`
    `login` variables
  `login_prompts`
    `login` variables
  `login_failure_msgs`
    `login` variables
  `login_non_failure_msgs`
    `login` variables
  `router_prompts`
    `login` variables
  `login_success_msgs`
    `login` variables
  `login_timeouts`
    `login` variables
  `non_ASCII_hosts`
    `login` variables
  `skip_logins_to`
    `login` variables
  `always_hot_login_ids`
    `login` variables
  `hot_login_ids`
    `login` variables
  `rlogin_id_okay_if_no_password_exposed`
    `login` variables
  `rpc_programs`
    `portmapper` variables
  `NFS_services`
    `portmapper` variables
  `RPC_okay`
    `portmapper` variables
  `RPC_okay_nets`
    `portmapper` variables
  `RPC_okay_services`
    `portmapper` variables
  `NFS_world_servers`
    `portmapper` variables
  `RPC_dump_okay`
    `portmapper` variables
  `any_RPC_okay`
    `portmapper` variables
  `suppress_pm_log`
    `portmapper` variables
  `weird_action`
    `weird` variables
  `weird_action_filters`
    `weird` variables
  `weird_ignore_host`
    `weird` variables
  `weird_do_not_ignore_repeats`
    `weird` variables
  attributes
    Attributes
  constant
    Statements
  initialization
    Initialization
  local
    Statements
  modifiability
    Modifiability
  overview
    Overview
  redefining
    Refinement
  refinement
    Refinement
  scope
    Statements
  scoping
    Scope
  typing
    Typing
version message
  Flags
VMS input editing
  `login` analyzer confusion | `login` analyzer confusion | `login` analyzer confusion
VMS login prompts
  `login` analyzer confusion
  \tt Username:
    `login` analyzer confusion
`VT666` terminal type backdoor
  `login` variables
`-W` flag
  Flags | Flags
walld
  `portmapper` variables | `portmapper` variables | `portmapper` event handlers | `portmapper` event handlers
watchdog
  Flags
watchdog timer expired
  run-time error
    Flags
`WATCHDOG_INTERVAL` internal variable
  Flags
``weird'' event
  Events handled by `conn_weird` | Events handled by `conn_weird` | Events handled by `conn_weird` | Events handled by `conn_weird` | Events handled by `conn_weird` | Events handled by `conn_weird` | Events handled by `conn_weird` | Events handled by `conn_weird` | Events handled by `conn_weird` | Events handled by `conn_weird` | Events handled by `conn_weird` | Events handled by `conn_weird` | Events handled by `conn_weird` | Events handled by `conn_weird` | Events handled by `conn_weird` | Events handled by `conn_weird` | Events handled by `conn_weird` | Events handled by `conn_weird` | Events handled by `conn_weird` | Events handled by `conn_weird` | Events handled by `conn_weird` | Events handled by `conn_weird` | Events handled by `conn_weird` | Events handled by `conn_weird` | Events handled by `conn_weird` | Events handled by `conn_weird` | Events handled by `conn_weird` | Events handled by `conn_weird` | Events handled by `conn_weird` | Events handled by `conn_weird` | Events handled by `conn_weird` | Events handled by `conn_weird` | Events handled by `conn_weird` | Events handled by `conn_weird` | Events handled by `conn_weird` | Events handled by `conn_weird` | Events handled by `conn_weird` | Events handled by `conn_weird` | Events handled by `conn_weird` | Events handled by `conn_weird` | Events handled by `conn_weird` | Events handled by `conn_weird` | Events handled by `conn_weird` | Events handled by `conn_weird` | Events handled by `conn_weird` | Events handled by `conn_weird` | Events handled by `conn_weird` | Events handled by `conn_weird` | Events handled by `conn_weird` | Events handled by `conn_weird` | Events handled by `conn_weird` | Events handled by `conn_weird` | Events handled by `conn_weird` | Events handled by `conn_weird` | Events handled by `conn_weird` | Events handled by `conn_weird_addl` | Events handled by `conn_weird_addl` | Events handled by `conn_weird_addl` | Events handled by `flow_weird` | Events handled by `flow_weird` | Events handled by `flow_weird` | Events handled by `flow_weird` | Events handled by `flow_weird` | Events handled by `flow_weird` | Events handled by `flow_weird` | Events handled by `flow_weird` | Events handled by `net_weird` | Events handled by `net_weird` | Events handled by `net_weird` | Events handled by `net_weird` | Events handled by `net_weird` | Events generated by the | Events generated by the
  `active_connection_reuse`
    Events handled by `conn_weird`
  `bad_HTTP_reply`
    Events handled by `conn_weird`
  `bad_HTTP_version`
    Events handled by `conn_weird`
  `bad_ICMP_checksum`
    Events handled by `conn_weird`
  `bad_ident_reply`
    Events handled by `conn_weird_addl`
  `bad_ident_request`
    Events handled by `conn_weird_addl`
  `bad_IP_checksum`
    Events handled by `net_weird`
  `bad_pm_port`
    Events generated by the
  `bad_rlogin_prolog`
    Events handled by `conn_weird`
  `bad_RPC`
    Events handled by `conn_weird`
  `bad_RPC_program`
    Events handled by `conn_weird`
  `bad_SYN_ack`
    Events handled by `conn_weird`
  `bad_TCP_checksum`
    Events handled by `conn_weird`
  `bad_TCP_header_len`
    Events handled by `net_weird`
  `bad_UDP_checksum`
    Events handled by `conn_weird`
  `baroque_SYN`
    Events handled by `conn_weird`
  `blank_in_HTTP_request`
    Events handled by `conn_weird`
  `connection_originator_SYN_ack`
    Events handled by `conn_weird`
  `data_after_reset`
    Events handled by `conn_weird`
  `data_before_established`
    Events handled by `conn_weird`
  `excess_RPC`
    Events handled by `conn_weird`
  `excessive_RPC_len`
    Events handled by `conn_weird`
  `excessively_large_fragment`
    Events handled by `flow_weird`
  `excessively_small_fragment`
    Events handled by `flow_weird`
  `FIN_advanced_last_seq`
    Events handled by `conn_weird`
  `FIN_after_reset`
    Events handled by `conn_weird`
  `FIN_storm`
    Events handled by `conn_weird`
  `fragment_inconsistency`
    Events handled by `flow_weird`
  `fragment_overlap`
    Events handled by `flow_weird`
  `fragment_protocol_inconsistency`
    Events handled by `flow_weird`
  `fragment_size_inconsistency`
    Events handled by `flow_weird`
  `fragment_with_DF`
    Events handled by `flow_weird`
  `HTTP_unknown_method`
    Events handled by `conn_weird`
  `HTTP_version_mismatch`
    Events handled by `conn_weird`
  `ident_request_addendum`
    Events handled by `conn_weird_addl`
  `inappropriate_FIN`
    Events handled by `conn_weird`
  `incompletely_captured_fragment`
    Events handled by `flow_weird`
  `internally_truncated_header`
    Events handled by `net_weird`
  `Land_attack`
    Events generated by the
  `multiple_HTTP_request_elements`
    Events handled by `conn_weird`
  `multiple_RPCs`
    Events handled by `conn_weird`
  `NUL_in_line`
    Events handled by `conn_weird`
  `originator_RPC_reply`
    Events handled by `conn_weird`
  `partial_finger_request`
    Events handled by `conn_weird`
  `partial_ftp_request`
    Events handled by `conn_weird`
  `partial_ident_request`
    Events handled by `conn_weird`
  `partial_portmapper_request`
    Events handled by `conn_weird`
  `partial_RPC`
    Events handled by `conn_weird`
  `pending_data_when_closed`
    Events handled by `conn_weird`
  `possible_split_routing`
    Events handled by `conn_weird`
  `premature_connection_reuse`
    Events handled by `conn_weird`
  `repeated_SYN_reply_wo_ack`
    Events handled by `conn_weird`
  `repeated_SYN_with_ack`
    Events handled by `conn_weird`
  `responder_RPC_call`
    Events handled by `conn_weird`
  `rlogin_text_after_rejected`
    Events handled by `conn_weird`
  `RPC_rexmit_inconsistency`
    Events handled by `conn_weird`
  `RST_storm`
    Events handled by `conn_weird`
  `RST_with_data`
    Events handled by `conn_weird`
  `simultaneous_open`
    Events handled by `conn_weird`
  `spontaneous_FIN`
    Events handled by `conn_weird`
  `spontaneous_RST`
    Events handled by `conn_weird`
  `SYN_after_close`
    Events handled by `conn_weird`
  `SYN_after_partial`
    Events handled by `conn_weird`
  `SYN_after_reset`
    Events handled by `conn_weird`
  `SYN_inside_connection`
    Events handled by `conn_weird`
  `SYN_seq_jump`
    Events handled by `conn_weird`
  `SYN_with_data`
    Events handled by `conn_weird`
  `TCP_christmas`
    Events handled by `conn_weird`
  `truncated_header`
    Events handled by `net_weird`
  `truncated_IP`
    Events handled by `net_weird`
  `UDP_datagram_length_mismatch`
    Events handled by `conn_weird`
  `unpaired_RPC_response`
    Events handled by `conn_weird`
  `unsolicited_SYN_response`
    Events handled by `conn_weird`
`weird` event summary file
  The `weird` Module
weird events
  The `weird` Module to Additional handlers for ``weird''
  actions
    Actions for ``weird'' events
  additional handlers
    Additional handlers for ``weird''
  generated by standard scripts
    Events generated by the
  handled by `conn_weird`
    Events handled by `conn_weird`
  handled by `conn_weird_addl`
    Events handled by `conn_weird_addl`
  handled by `flow_weird`
    Events handled by `flow_weird`
  handled by `net_weird`
    Events handled by `net_weird`
  prevalence in actual network traffic
    The `weird` Module
`weird` module
  The `weird` Module
`weird_action` variable
  `weird` variables
`weird_action_filters` variable
  `weird` variables
`weird_do_not_ignore_repeats` variable
  `weird` variables
`WEIRD_FILE` action
  Actions for ``weird'' events
`WEIRD_IGNORE` action
  Actions for ``weird'' events
`weird_ignore_host` variable
  `weird` variables
`WEIRD_LOG_ALWAYS` action
  Actions for ``weird'' events
`WEIRD_LOG_ONCE` action
  Actions for ``weird'' events
`WEIRD_LOG_PER_CONN` action
  Actions for ``weird'' events
`WEIRD_LOG_PER_ORIG` action
  Actions for ``weird'' events
`WEIRD_UNSPECIFIED` action
  Actions for ``weird'' events
whitespace
  in statements
    Statements
width
  of formatted strings
    Predefined Functions
Windows
  not supported
    Supported platforms
write file
  control over what's recorded
    Predefined Functions
`&write_expire` attribute
  Table Attributes
writing `tcpdump` files
  Flags
`wrong number of fmt arguments`
  Predefined Functions
wrong number of fmt arguments
  run-time error
    Predefined Functions
wrong number of length arguments
  run-time error
    Predefined Functions
www.anticode.com
  `login` variables
`wwwroot` sensitive POST URI
  `http` variables
yield
  of a table
    Tables
ypserv
  `portmapper` variables

# About this document ...

The Bro 0.8 User Manual

This document was generated using the LaTeX2`HTML` translator Version 2002-2 (1.70)

Copyright © 1993, 1994, 1995, 1996, Nikos Drakos, Computer Based Learning Unit, University of Leeds.
Copyright © 1997, 1998, 1999, Ross Moore, Mathematics Department, Macquarie University, Sydney.

The command line arguments were:
latex2html `-split 0 -index_in_navigation doc-html`

The translation was initiated by Vern Paxson on 2002-11-17

#### Footnotes

... run.2.1
  Providing that these programs have been recompiled with the corrected libpcap noted above.
... transferred,7.1
  Deficiency: Actually, for state `S1` data may have been transferred, and so this assumption should be corrected in that case.
... multicasts.7.2
  I don't know how much this type of access is actually used in practice, but experience shows that requests for ypserv directed to that address pop up not infrequently.