mirror of
https://github.com/zeek/zeek.git
synced 2025-10-14 04:28:20 +00:00
Merge remote-tracking branch 'origin/topic/jsiwek/gre'
* origin/topic/jsiwek/gre: Simplify FragReassembler memory management. BIT-867 - Support GRE tunnel decapsulation. BIT-867 #merged
This commit is contained in:
commit
ba9571f9ff
17 changed files with 232 additions and 17 deletions
9
CHANGES
9
CHANGES
|
@ -1,4 +1,13 @@
|
|||
|
||||
2.2-105 | 2014-01-20 12:16:48 -0800
|
||||
|
||||
* Support GRE tunnel decapsulation, including enhanced GRE headers.
|
||||
GRE tunnels are treated just like IP-in-IP tunnels by parsing past
|
||||
the GRE header in between the delivery and payload IP packets.
|
||||
Addresses BIT-867. (Jon Siwek)
|
||||
|
||||
* Simplify FragReassembler memory management. (Jon Siwek)
|
||||
|
||||
2.2-102 | 2014-01-20 12:00:29 -0800
|
||||
|
||||
* Include file information (MIME type and description) into notice
|
||||
|
|
4
NEWS
4
NEWS
|
@ -20,6 +20,10 @@ Dependencies
|
|||
New Functionality
|
||||
-----------------
|
||||
|
||||
- Support for GRE tunnel decapsulation, including enhanced GRE
|
||||
headers. GRE tunnels are treated just like IP-in-IP tunnels by
|
||||
parsing past the GRE header in between the delivery and payload IP
|
||||
packets.
|
||||
|
||||
Changed Functionality
|
||||
---------------------
|
||||
|
|
2
VERSION
2
VERSION
|
@ -1 +1 @@
|
|||
2.2-102
|
||||
2.2-105
|
||||
|
|
|
@ -3057,6 +3057,9 @@ export {
|
|||
## Toggle whether to do GTPv1 decapsulation.
|
||||
const enable_gtpv1 = T &redef;
|
||||
|
||||
## Toggle whether to do GRE decapsulation.
|
||||
const enable_gre = T &redef;
|
||||
|
||||
## With this option set, the Teredo analysis will first check to see if
|
||||
## other protocol analyzers have confirmed that they think they're
|
||||
## parsing the right protocol and only continue with Teredo tunnel
|
||||
|
@ -3082,7 +3085,8 @@ export {
|
|||
## may work better.
|
||||
const delay_gtp_confirmation = F &redef;
|
||||
|
||||
## How often to cleanup internal state for inactive IP tunnels.
|
||||
## How often to cleanup internal state for inactive IP tunnels
|
||||
## (includes GRE tunnels).
|
||||
const ip_tunnel_timeout = 24hrs &redef;
|
||||
} # end export
|
||||
module GLOBAL;
|
||||
|
|
134
src/Sessions.cc
134
src/Sessions.cc
|
@ -376,6 +376,31 @@ int NetSessions::CheckConnectionTag(Connection* conn)
|
|||
return 1;
|
||||
}
|
||||
|
||||
static unsigned int gre_header_len(uint16 flags)
|
||||
{
|
||||
unsigned int len = 4; // Always has 2 byte flags and 2 byte protocol type.
|
||||
|
||||
if ( flags & 0x8000 )
|
||||
// Checksum/Reserved1 present.
|
||||
len += 4;
|
||||
|
||||
// Not considering routing presence bit since it's deprecated ...
|
||||
|
||||
if ( flags & 0x2000 )
|
||||
// Key present.
|
||||
len += 4;
|
||||
|
||||
if ( flags & 0x1000 )
|
||||
// Sequence present.
|
||||
len += 4;
|
||||
|
||||
if ( flags & 0x0080 )
|
||||
// Acknowledgement present.
|
||||
len += 4;
|
||||
|
||||
return len;
|
||||
}
|
||||
|
||||
void NetSessions::DoNextPacket(double t, const struct pcap_pkthdr* hdr,
|
||||
const IP_Hdr* ip_hdr, const u_char* const pkt,
|
||||
int hdr_size, const EncapsulationStack* encapsulation)
|
||||
|
@ -446,6 +471,8 @@ void NetSessions::DoNextPacket(double t, const struct pcap_pkthdr* hdr,
|
|||
}
|
||||
}
|
||||
|
||||
FragReassemblerTracker frt(this, f);
|
||||
|
||||
len -= ip_hdr_len; // remove IP header
|
||||
caplen -= ip_hdr_len;
|
||||
|
||||
|
@ -460,7 +487,7 @@ void NetSessions::DoNextPacket(double t, const struct pcap_pkthdr* hdr,
|
|||
vl->append(ip_hdr->BuildPktHdrVal());
|
||||
mgr.QueueEvent(esp_packet, vl);
|
||||
}
|
||||
Remove(f);
|
||||
|
||||
// Can't do more since upper-layer payloads are going to be encrypted.
|
||||
return;
|
||||
}
|
||||
|
@ -475,7 +502,6 @@ void NetSessions::DoNextPacket(double t, const struct pcap_pkthdr* hdr,
|
|||
if ( ! ignore_checksums && mobility_header_checksum(ip_hdr) != 0xffff )
|
||||
{
|
||||
Weird("bad_MH_checksum", hdr, pkt, encapsulation);
|
||||
Remove(f);
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -489,7 +515,6 @@ void NetSessions::DoNextPacket(double t, const struct pcap_pkthdr* hdr,
|
|||
if ( ip_hdr->NextProto() != IPPROTO_NONE )
|
||||
Weird("mobility_piggyback", hdr, pkt, encapsulation);
|
||||
|
||||
Remove(f);
|
||||
return;
|
||||
}
|
||||
#endif
|
||||
|
@ -497,10 +522,7 @@ void NetSessions::DoNextPacket(double t, const struct pcap_pkthdr* hdr,
|
|||
int proto = ip_hdr->NextProto();
|
||||
|
||||
if ( CheckHeaderTrunc(proto, len, caplen, hdr, pkt, encapsulation) )
|
||||
{
|
||||
Remove(f);
|
||||
return;
|
||||
}
|
||||
|
||||
const u_char* data = ip_hdr->Payload();
|
||||
|
||||
|
@ -562,13 +584,100 @@ void NetSessions::DoNextPacket(double t, const struct pcap_pkthdr* hdr,
|
|||
break;
|
||||
}
|
||||
|
||||
case IPPROTO_GRE:
|
||||
{
|
||||
if ( ! BifConst::Tunnel::enable_gre )
|
||||
{
|
||||
Weird("GRE_tunnel", ip_hdr, encapsulation);
|
||||
return;
|
||||
}
|
||||
|
||||
uint16 flags_ver = ntohs(*((uint16*)(data + 0)));
|
||||
uint16 proto_typ = ntohs(*((uint16*)(data + 2)));
|
||||
int gre_version = flags_ver & 0x0007;
|
||||
|
||||
if ( gre_version != 0 && gre_version != 1 )
|
||||
{
|
||||
Weird(fmt("unknown_gre_version_%d", gre_version), ip_hdr,
|
||||
encapsulation);
|
||||
return;
|
||||
}
|
||||
|
||||
if ( gre_version == 0 )
|
||||
{
|
||||
if ( proto_typ != 0x0800 && proto_typ != 0x86dd )
|
||||
{
|
||||
// Not IPv4/IPv6 payload.
|
||||
Weird(fmt("unknown_gre_protocol_%"PRIu16, proto_typ), ip_hdr,
|
||||
encapsulation);
|
||||
return;
|
||||
}
|
||||
|
||||
proto = (proto_typ == 0x0800) ? IPPROTO_IPV4 : IPPROTO_IPV6;
|
||||
}
|
||||
|
||||
else // gre_version == 1
|
||||
{
|
||||
if ( proto_typ != 0x880b )
|
||||
{
|
||||
// Enhanced GRE payload must be PPP.
|
||||
Weird("egre_protocol_type", ip_hdr, encapsulation);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
if ( flags_ver & 0x4000 )
|
||||
{
|
||||
// RFC 2784 deprecates the variable length routing field
|
||||
// specified by RFC 1701. It could be parsed here, but easiest
|
||||
// to just skip for now.
|
||||
Weird("gre_routing", ip_hdr, encapsulation);
|
||||
return;
|
||||
}
|
||||
|
||||
if ( flags_ver & 0x0078 )
|
||||
{
|
||||
// Expect last 4 bits of flags are reserved, undefined.
|
||||
Weird("unknown_gre_flags", ip_hdr, encapsulation);
|
||||
return;
|
||||
}
|
||||
|
||||
unsigned int gre_len = gre_header_len(flags_ver);
|
||||
unsigned int ppp_len = gre_version == 1 ? 1 : 0;
|
||||
|
||||
if ( len < gre_len + ppp_len || caplen < gre_len + ppp_len )
|
||||
{
|
||||
Weird("truncated_GRE", ip_hdr, encapsulation);
|
||||
return;
|
||||
}
|
||||
|
||||
if ( gre_version == 1 )
|
||||
{
|
||||
int ppp_proto = *((uint8*)(data + gre_len));
|
||||
|
||||
if ( ppp_proto != 0x0021 && ppp_proto != 0x0057 )
|
||||
{
|
||||
Weird("non_ip_packet_in_egre", ip_hdr, encapsulation);
|
||||
return;
|
||||
}
|
||||
|
||||
proto = (ppp_proto == 0x0021) ? IPPROTO_IPV4 : IPPROTO_IPV6;
|
||||
}
|
||||
|
||||
data += gre_len + ppp_len;
|
||||
len -= gre_len + ppp_len;
|
||||
caplen -= gre_len + ppp_len;
|
||||
|
||||
// Treat GRE tunnel like IP tunnels, fallthrough to logic below now
|
||||
// that GRE header is stripped and only payload packet remains.
|
||||
}
|
||||
|
||||
case IPPROTO_IPV4:
|
||||
case IPPROTO_IPV6:
|
||||
{
|
||||
if ( ! BifConst::Tunnel::enable_ip )
|
||||
{
|
||||
Weird("IP_tunnel", ip_hdr, encapsulation);
|
||||
Remove(f);
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -576,7 +685,6 @@ void NetSessions::DoNextPacket(double t, const struct pcap_pkthdr* hdr,
|
|||
encapsulation->Depth() >= BifConst::Tunnel::max_depth )
|
||||
{
|
||||
Weird("exceeded_tunnel_max_depth", ip_hdr, encapsulation);
|
||||
Remove(f);
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -593,7 +701,6 @@ void NetSessions::DoNextPacket(double t, const struct pcap_pkthdr* hdr,
|
|||
if ( result != 0 )
|
||||
{
|
||||
delete inner;
|
||||
Remove(f);
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -620,7 +727,6 @@ void NetSessions::DoNextPacket(double t, const struct pcap_pkthdr* hdr,
|
|||
DoNextInnerPacket(t, hdr, inner, encapsulation,
|
||||
ip_tunnels[tunnel_idx].first);
|
||||
|
||||
Remove(f);
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -633,13 +739,11 @@ void NetSessions::DoNextPacket(double t, const struct pcap_pkthdr* hdr,
|
|||
encapsulation->LastType() == BifEnum::Tunnel::TEREDO ) )
|
||||
Weird("ipv6_no_next", hdr, pkt);
|
||||
|
||||
Remove(f);
|
||||
return;
|
||||
}
|
||||
|
||||
default:
|
||||
Weird(fmt("unknown_protocol_%d", proto), hdr, pkt, encapsulation);
|
||||
Remove(f);
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -665,7 +769,6 @@ void NetSessions::DoNextPacket(double t, const struct pcap_pkthdr* hdr,
|
|||
if ( consistent < 0 )
|
||||
{
|
||||
delete h;
|
||||
Remove(f);
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -689,7 +792,6 @@ void NetSessions::DoNextPacket(double t, const struct pcap_pkthdr* hdr,
|
|||
if ( ! conn )
|
||||
{
|
||||
delete h;
|
||||
Remove(f);
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -721,7 +823,6 @@ void NetSessions::DoNextPacket(double t, const struct pcap_pkthdr* hdr,
|
|||
{
|
||||
// Above we already recorded the fragment in its entirety.
|
||||
f->DeleteTimer();
|
||||
Remove(f);
|
||||
}
|
||||
|
||||
else if ( record_packet )
|
||||
|
@ -822,6 +923,9 @@ bool NetSessions::CheckHeaderTrunc(int proto, uint32 len, uint32 caplen,
|
|||
case IPPROTO_NONE:
|
||||
min_hdr_len = 0;
|
||||
break;
|
||||
case IPPROTO_GRE:
|
||||
min_hdr_len = 4;
|
||||
break;
|
||||
case IPPROTO_ICMP:
|
||||
case IPPROTO_ICMPV6:
|
||||
default:
|
||||
|
|
|
@ -286,6 +286,21 @@ protected:
|
|||
NetSessions::IPPair tunnel_idx;
|
||||
};
|
||||
|
||||
|
||||
class FragReassemblerTracker {
|
||||
public:
|
||||
FragReassemblerTracker(NetSessions* s, FragReassembler* f)
|
||||
: net_sessions(s), frag_reassembler(f)
|
||||
{ }
|
||||
|
||||
~FragReassemblerTracker()
|
||||
{ net_sessions->Remove(frag_reassembler); }
|
||||
|
||||
private:
|
||||
NetSessions* net_sessions;
|
||||
FragReassembler* frag_reassembler;
|
||||
};
|
||||
|
||||
// Manager for the currently active sessions.
|
||||
extern NetSessions* sessions;
|
||||
|
||||
|
|
|
@ -17,6 +17,7 @@ const Tunnel::enable_ip: bool;
|
|||
const Tunnel::enable_ayiya: bool;
|
||||
const Tunnel::enable_teredo: bool;
|
||||
const Tunnel::enable_gtpv1: bool;
|
||||
const Tunnel::enable_gre: bool;
|
||||
const Tunnel::yielding_teredo_decapsulation: bool;
|
||||
const Tunnel::delay_teredo_confirmation: bool;
|
||||
const Tunnel::delay_gtp_confirmation: bool;
|
||||
|
|
12
testing/btest/Baseline/core.tunnels.gre-in-gre/conn.log
Normal file
12
testing/btest/Baseline/core.tunnels.gre-in-gre/conn.log
Normal file
|
@ -0,0 +1,12 @@
|
|||
#separator \x09
|
||||
#set_separator ,
|
||||
#empty_field (empty)
|
||||
#unset_field -
|
||||
#path conn
|
||||
#open 2014-01-16-21-51-36
|
||||
#fields ts uid id.orig_h id.orig_p id.resp_h id.resp_p proto service duration orig_bytes resp_bytes conn_state local_orig missed_bytes history orig_pkts orig_ip_bytes resp_pkts resp_ip_bytes tunnel_parents
|
||||
#types time string addr port addr port enum string interval count count string bool count string count count count count table[string]
|
||||
1341436440.002928 CRJuHdVW0XPVINV8a 3.3.3.2 520 224.0.0.9 520 udp - 26.148268 48 0 S0 - 0 D 2 104 0 0 CjhGID4nQcgTWjvg4c
|
||||
1341436424.378840 CsRx2w45OKnoww6xl4 3.3.3.1 520 224.0.0.9 520 udp - 28.555457 168 0 S0 - 0 D 2 224 0 0 CjhGID4nQcgTWjvg4c
|
||||
1341436424.204043 CCvvfg3TEfuqmmG4bh 10.10.25.1 8 192.168.1.2 0 icmp - 42.380221 22464 22464 OTH - 0 - 312 31200 312 31200 CjhGID4nQcgTWjvg4c
|
||||
#close 2014-01-16-21-51-36
|
11
testing/btest/Baseline/core.tunnels.gre-in-gre/tunnel.log
Normal file
11
testing/btest/Baseline/core.tunnels.gre-in-gre/tunnel.log
Normal file
|
@ -0,0 +1,11 @@
|
|||
#separator \x09
|
||||
#set_separator ,
|
||||
#empty_field (empty)
|
||||
#unset_field -
|
||||
#path tunnel
|
||||
#open 2014-01-16-21-51-36
|
||||
#fields ts uid id.orig_h id.orig_p id.resp_h id.resp_p tunnel_type action
|
||||
#types time string addr port addr port enum enum
|
||||
1341436424.204043 CXWv6p3arKYeMETxOg 72.205.54.70 0 86.106.164.150 0 Tunnel::IP Tunnel::DISCOVER
|
||||
1341436424.204043 CjhGID4nQcgTWjvg4c 10.10.11.2 0 10.10.13.2 0 Tunnel::IP Tunnel::DISCOVER
|
||||
#close 2014-01-16-21-51-36
|
16
testing/btest/Baseline/core.tunnels.gre/conn.log
Normal file
16
testing/btest/Baseline/core.tunnels.gre/conn.log
Normal file
|
@ -0,0 +1,16 @@
|
|||
#separator \x09
|
||||
#set_separator ,
|
||||
#empty_field (empty)
|
||||
#unset_field -
|
||||
#path conn
|
||||
#open 2014-01-16-21-51-12
|
||||
#fields ts uid id.orig_h id.orig_p id.resp_h id.resp_p proto service duration orig_bytes resp_bytes conn_state local_orig missed_bytes history orig_pkts orig_ip_bytes resp_pkts resp_ip_bytes tunnel_parents
|
||||
#types time string addr port addr port enum string interval count count string bool count string count count count count table[string]
|
||||
1055289978.756932 CsRx2w45OKnoww6xl4 66.59.111.190 40264 172.28.2.3 22 tcp ssh 3.157831 952 1671 SF - 0 ShAdDaFf 12 1584 10 2199 CXWv6p3arKYeMETxOg
|
||||
1055289987.055189 CRJuHdVW0XPVINV8a 66.59.111.190 37675 172.28.2.3 53 udp dns 5.001141 66 0 S0 - 0 D 2 122 0 0 CXWv6p3arKYeMETxOg
|
||||
1055289996.849099 CIPOse170MGiRM1Qf4 66.59.111.190 123 129.170.17.4 123 udp - 0.072374 48 48 SF - 0 Dd 1 76 1 76 CXWv6p3arKYeMETxOg
|
||||
1055289973.849878 CCvvfg3TEfuqmmG4bh 66.59.111.190 123 18.26.4.105 123 udp - 0.074086 48 48 SF - 0 Dd 1 76 1 76 CXWv6p3arKYeMETxOg
|
||||
1055289992.849231 C6pKV8GSxOnSLghOa 66.59.111.190 123 66.59.111.182 123 udp - 0.056629 48 48 SF - 0 Dd 1 76 1 76 CXWv6p3arKYeMETxOg
|
||||
1055289968.793044 CjhGID4nQcgTWjvg4c 66.59.111.190 8 172.28.2.3 0 icmp - 3.061298 224 224 OTH - 0 - 4 336 4 336 CXWv6p3arKYeMETxOg
|
||||
1055289987.106744 CPbrpk1qSsw6ESzHV4 172.28.2.3 3 66.59.111.190 3 icmp - 4.994662 122 0 OTH - 0 - 2 178 0 0 CXWv6p3arKYeMETxOg
|
||||
#close 2014-01-16-21-51-12
|
11
testing/btest/Baseline/core.tunnels.gre/dns.log
Normal file
11
testing/btest/Baseline/core.tunnels.gre/dns.log
Normal file
|
@ -0,0 +1,11 @@
|
|||
#separator \x09
|
||||
#set_separator ,
|
||||
#empty_field (empty)
|
||||
#unset_field -
|
||||
#path dns
|
||||
#open 2014-01-16-21-51-12
|
||||
#fields ts uid id.orig_h id.orig_p id.resp_h id.resp_p proto trans_id query qclass qclass_name qtype qtype_name rcode rcode_name AA TC RD RA Z answers TTLs rejected
|
||||
#types time string addr port addr port enum count string count string count string count string bool bool bool bool count vector[string] vector[interval] bool
|
||||
1055289987.055189 CRJuHdVW0XPVINV8a 66.59.111.190 37675 172.28.2.3 53 udp 48554 www.gleeble.org 1 C_INTERNET 255 * - - F F T F 0 - - F
|
||||
1055289992.056330 CRJuHdVW0XPVINV8a 66.59.111.190 37675 172.28.2.3 53 udp 48554 www.gleeble.org 1 C_INTERNET 255 * - - F F T F 0 - - F
|
||||
#close 2014-01-16-21-51-12
|
10
testing/btest/Baseline/core.tunnels.gre/ssh.log
Normal file
10
testing/btest/Baseline/core.tunnels.gre/ssh.log
Normal file
|
@ -0,0 +1,10 @@
|
|||
#separator \x09
|
||||
#set_separator ,
|
||||
#empty_field (empty)
|
||||
#unset_field -
|
||||
#path ssh
|
||||
#open 2014-01-16-21-51-12
|
||||
#fields ts uid id.orig_h id.orig_p id.resp_h id.resp_p status direction client server
|
||||
#types time string addr port addr port string enum string string
|
||||
1055289978.855137 CsRx2w45OKnoww6xl4 66.59.111.190 40264 172.28.2.3 22 failure INBOUND SSH-2.0-OpenSSH_3.6.1p1 SSH-1.99-OpenSSH_3.1p1
|
||||
#close 2014-01-16-21-51-12
|
10
testing/btest/Baseline/core.tunnels.gre/tunnel.log
Normal file
10
testing/btest/Baseline/core.tunnels.gre/tunnel.log
Normal file
|
@ -0,0 +1,10 @@
|
|||
#separator \x09
|
||||
#set_separator ,
|
||||
#empty_field (empty)
|
||||
#unset_field -
|
||||
#path tunnel
|
||||
#open 2014-01-16-21-51-12
|
||||
#fields ts uid id.orig_h id.orig_p id.resp_h id.resp_p tunnel_type action
|
||||
#types time string addr port addr port enum enum
|
||||
1055289968.793044 CXWv6p3arKYeMETxOg 172.27.1.66 0 66.59.109.137 0 Tunnel::IP Tunnel::DISCOVER
|
||||
#close 2014-01-16-21-51-12
|
BIN
testing/btest/Traces/tunnels/gre-sample.pcap
Normal file
BIN
testing/btest/Traces/tunnels/gre-sample.pcap
Normal file
Binary file not shown.
BIN
testing/btest/Traces/tunnels/gre-within-gre.pcap
Normal file
BIN
testing/btest/Traces/tunnels/gre-within-gre.pcap
Normal file
Binary file not shown.
3
testing/btest/core/tunnels/gre-in-gre.test
Normal file
3
testing/btest/core/tunnels/gre-in-gre.test
Normal file
|
@ -0,0 +1,3 @@
|
|||
# @TEST-EXEC: bro -r $TRACES/tunnels/gre-within-gre.pcap
|
||||
# @TEST-EXEC: btest-diff conn.log
|
||||
# @TEST-EXEC: btest-diff tunnel.log
|
5
testing/btest/core/tunnels/gre.test
Normal file
5
testing/btest/core/tunnels/gre.test
Normal file
|
@ -0,0 +1,5 @@
|
|||
# @TEST-EXEC: bro -r $TRACES/tunnels/gre-sample.pcap
|
||||
# @TEST-EXEC: btest-diff conn.log
|
||||
# @TEST-EXEC: btest-diff tunnel.log
|
||||
# @TEST-EXEC: btest-diff dns.log
|
||||
# @TEST-EXEC: btest-diff ssh.log
|
Loading…
Add table
Add a link
Reference in a new issue