In the old subversion repository there's a TFTP analyzer (TFTP.h and TFTP.cc, with an accompanying new tftp.bro). It was never integrated due to a significant design question about just how to treat TFTP sessions, given that they can change port numbers. Below is an email exchange with Robin discussing the problem.
On Fri, Apr 27, 2007 at 10:02 -0700, you [Vern] wrote:
> The way TFTP works, a request will have a tuple
> (A) <src-addr, src-port, dst-addr, 69/udp>
> (where of course 69/udp needs to not be wired in but rather amenable to
> DPD, but I'm using the concrete value here to help with exposition).
> The reply has a tuple:
> (B) <dst-addr, dst-port, src-addr, src-port>
> where dst-port needn't be 69/udp.
I don't like the idea of migrating the analyzer from one connection
to the other (for the same reasons you don't like it either , but
belows's an idea which could work if I understood your summary of
TFTP correctly. It does however assume that the TFTP analyzer does
not need to correlate core state between originator and responder
(though perhaps that could also be hacked into the scheme somehow).
> This is clearly somewhat related with FTP data channel establishement,
Right, perhaps we can leverage the same meachnism.
So, if the first client packet comes in:
<src-addr, src-port, dst-addr, 69/udp>
then Bro will instantiate connection1 and assign the TFTP analyzer
to it. The analyzer can then register another TFTP analyzer for a
potential follow-up connection via the expect_connection()
mechanism (works on both core- and script-level):
expect_connection(dst-addr, src-addr, src-port, TFTP)
If then the reply <dst-addr, dst-port, src-addr, src-port> follows,
we have two cases:
(1) dst_port == 69/udp
Bro associates it with connection1 and we're fine. The
expect_connection() will eventually time-out (or we add an
"unexpect_connection" to remove the entry).
(2) dst_port != 69/udp
Bro opens a new connection2 with the wrong direction but also
with the TFTP analyzer.
The TFTP analyzer can check whether dst-port is not 69/udp. If
so, then we are in this case and it can call
connection2->FlipRoles() to flip the endpoints. From that on, it
can proceed as usual; all subsequent packets will arive on
connection2 (except for retransmissions of the initial request
which will still go to connection1 and can be handled there).
The script-level needs to cope with TFTP events coming from two
different connections but that should be doable I'd think.
Does this help?
- peculiarities that arise due to missing or reordered packets
> (such as monitor sees the client's activity on the second
> connection prior to the server's activity, and thus the
> direction is reversed)
Not sure about these but there's likley no optimal solution for them.