[Bro-Dev] Decapsulating "payload" tunnels

Robin Sommer robin at icir.org
Thu Apr 26 19:34:34 PDT 2012

Thinking about this some more, below's an idea how we could structure
it. It's messy, but we don't have much of a way around that without
doing some major restructuring. But this would at least encapsulate
the messieness somewhat. Note, I haven't fully thought this through,
so there might be more stumling blocks; there often are some
dependencies internally that are hard to spot before starting to work
on the code ...

That said, how about this:

We create a new class TunnelConnection that encapsulates that all the
messy stuff. Interface could look something liek this:

    class TunnelConnection {
        // Associate a (fake) conn ID with the tunnel.
        TunnelConnection(ConnID id, Connection *parent, <whatever else we need>);

        // Feed data in for parsing.
        void NextStream(<payload data>)   // See below.

        [... probably more methods ...]

        Conn* fake_conn;
        Conn* parent;

The TunnelConnection internally creates a new (fake) Connection
object, stores it, and uses it for all the parsing when it needs a
Connection object. But we don't store that Connection in the normal
session tables.

Instead, NetSessions gets a new method:

    TunnelConnection* NewTunnelConnection(ConnID id, <give it what it needs>);

The higher-level analyzers that decapsulate the tunnel use
NewTunnelConnection() to get a tunnel and then feed data in via
NextStream(). That method does whatever's necessary to pass data to
the parsers, faking IP packets if necessary (but see below).

NetSessions tracks all TunnelConnections in their own dictionary
(similar to tcp_conns, udp_conns, icmp_conns) and handles state
management (i.e., removes if the parent connection goes away).

As Seth suggested, we should short-circuit the tunnel analysis to skip
the transport-layer where we don't have one. I'm not totally sure how
to do that best, but one option would be internally add an new TUNNEL
transport-layer besides the standard TCP/UDP/ICMP ones (drawback:
there are a number of locations that currently expect to not see other
transport-layers than the current set).

About faking IP packets: we may not be able to avoid that---but we can
try. :) The stream-based Analyzer interface doesn't need a packet,
just data chunks. We might be able to directly feed in there.[1]
(that's why the method above is called NextStream() :).


[1] Without further work this would break signature matching though.

Robin Sommer * Phone +1 (510) 722-6541 * robin at icir.org
ICSI/LBNL    * Fax   +1 (510) 666-2956 *   www.icir.org

More information about the bro-dev mailing list