[Bro-Dev] Tunnels

Gregor Maier gregor at icir.org
Thu Jul 28 13:49:03 PDT 2011


in NetSessions::DispatchPacket() Bro has some code to decapsulate some 

The first one uses encap_hdr_size (and udp_tunnel_port). It appears that 
it expects an IP header and if it finds one(*) and if encap_hdr_size>0 
then it will add skip encap_hdr_size and assume that the "interesting" 
part of the packet starts there. I was wondering why the code checks 
whether there is an IP header before skipping the fixed encap_hdr_bytes? 
Note that there is also the option to only skip if the packet is UDP and 
has a particular destination port (udp_tunnel_port). For this we do need 
to look for the IP header....
I think there might be a misplaced "else" here (i.e., the else belongs 
to a different if)

(*) it assumes there is one and just checks whether the caplen is long 
enough to contain the full IP header according to IP header length.

The other way it does tunnel decapsulation is done when 
parse_udp_tunnels is set. If the packet contains an IP header + UDP 
header the code checks whether the UDP payload looks like an IP packet 
and if so, then it will skip over these initial IP+UDP header. (Thus 
this code decapsulates IP-over-UDP). If udp_tunnel_port is specified 
then this code will limit its decapsulation to UDP packet with that 
destination port.

Some problems/concerns/questions:

* What was the intention of this code?
* All this happens before IP fragmentation. Shouldn't this be after
   defragmentation (and then re-inject the decapsulated packets before
   the de-fragmentation in the case that the tunneled IP is fragmented
   as well)
* The whole code is hard-code for IPv4 and doesn't check whether the
   initial IP header is actually a valid IP header (it assumes it is and
   just used IP header length). For IPv6 or ARP packets this code would
   obviously be incorrect (and possibly the code would incorrectly
   decapsulate something it shouldn't)
* While the code checks that there is enough packet data for the IP
   header, it does not check whether there is enough data for the UDP
   header before accessing uh_len and uh_dport.
   In the 2nd case it also doesn't check whether there's enough captured
   data to contain the encapsulated packet (Bro does look at this data
   for its heuristic that checks whether there is an IP header here)
* What should we do with this? Fix? Remove? Modify?

Note, the reason I was looking at this code is that I want to write 
something that can decapsulate tunneled IPv6 packets (6in4, 6to4, Teredo).

Gregor Maier
<gregor at icir.org>  <gregor at icsi.berkeley.edu>
Int. Computer Science Institute (ICSI)
1947 Center St., Ste. 600
Berkeley, CA 94704, USA

More information about the bro-dev mailing list