mirror of
https://github.com/zeek/zeek.git
synced 2025-10-15 04:58:21 +00:00
Merge remote-tracking branch 'origin/topic/jsiwek/skip-rh0-segleft'
* origin/topic/jsiwek/skip-rh0-segleft: Improve handling of IPv6 Routing Type 0 headers. Closes #804.
This commit is contained in:
commit
de7300f999
14 changed files with 111 additions and 5 deletions
17
CHANGES
17
CHANGES
|
@ -1,4 +1,21 @@
|
||||||
|
|
||||||
|
2.0-184 | 2012-03-28 15:11:11 -0700
|
||||||
|
|
||||||
|
* Improve handling of IPv6 Routing Type 0 headers. (Jon Siwek)
|
||||||
|
|
||||||
|
- For RH0 headers with non-zero segments left, a
|
||||||
|
"routing0_segleft" flow_weird event is raised (with a
|
||||||
|
destination indicating the last address in the routing header),
|
||||||
|
and an "rh0_segleft" event can also be handled if the other
|
||||||
|
contents of the packet header are of interest. No further
|
||||||
|
analysis is done as the complexity required to correctly
|
||||||
|
identify destination endpoints of connections doesn't seem worth
|
||||||
|
it as RH0 has been deprecated by RFC 5095.
|
||||||
|
|
||||||
|
- For RH0 headers without any segments left, a "routing0_header"
|
||||||
|
flow_weird event is raised, but further analysis still occurs as
|
||||||
|
normal.
|
||||||
|
|
||||||
2.0-182 | 2012-03-28 15:01:57 -0700
|
2.0-182 | 2012-03-28 15:01:57 -0700
|
||||||
|
|
||||||
* Remove dead tcp_checksum function from net_util. (Jon Siwek)
|
* Remove dead tcp_checksum function from net_util. (Jon Siwek)
|
||||||
|
|
2
VERSION
2
VERSION
|
@ -1 +1 @@
|
||||||
2.0-182
|
2.0-184
|
||||||
|
|
18
src/IP.cc
18
src/IP.cc
|
@ -305,6 +305,24 @@ void IPv6_Hdr_Chain::Init(const struct ip6_hdr* ip6, bool set_next, uint16 next)
|
||||||
|
|
||||||
chain.push_back(p);
|
chain.push_back(p);
|
||||||
|
|
||||||
|
// RFC 5095 deprecates routing type 0 headers, so raise weirds for that.
|
||||||
|
if ( current_type == IPPROTO_ROUTING &&
|
||||||
|
((const struct ip6_rthdr*)hdrs)->ip6r_type == 0 )
|
||||||
|
{
|
||||||
|
IPAddr src(((const struct ip6_hdr*)(chain[0]->Data()))->ip6_src);
|
||||||
|
|
||||||
|
if ( ((const struct ip6_rthdr*)hdrs)->ip6r_segleft > 0 )
|
||||||
|
{
|
||||||
|
const in6_addr* a = (const in6_addr*)(hdrs+len-16);
|
||||||
|
reporter->Weird(src, *a, "routing0_segleft");
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
IPAddr dst(((const struct ip6_hdr*)(chain[0]->Data()))->ip6_dst);
|
||||||
|
reporter->Weird(src, dst, "routing0_header");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
hdrs += len;
|
hdrs += len;
|
||||||
length += len;
|
length += len;
|
||||||
} while ( current_type != IPPROTO_FRAGMENT &&
|
} while ( current_type != IPPROTO_FRAGMENT &&
|
||||||
|
|
21
src/IP.h
21
src/IP.h
|
@ -171,6 +171,20 @@ public:
|
||||||
{ return IsFragment() ?
|
{ return IsFragment() ?
|
||||||
(ntohs(GetFragHdr()->ip6f_offlg) & 0x0001) != 0 : 0; }
|
(ntohs(GetFragHdr()->ip6f_offlg) & 0x0001) != 0 : 0; }
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns whether the chain contains a routing type 0 extension header
|
||||||
|
* with nonzero segments left.
|
||||||
|
*/
|
||||||
|
bool RH0SegLeft() const
|
||||||
|
{
|
||||||
|
for ( size_t i = 0; i < chain.size(); ++i )
|
||||||
|
if ( chain[i]->Type() == IPPROTO_ROUTING &&
|
||||||
|
((const struct ip6_rthdr*)chain[i]->Data())->ip6r_type == 0 &&
|
||||||
|
((const struct ip6_rthdr*)chain[i]->Data())->ip6r_segleft > 0 )
|
||||||
|
return true;
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns a vector of ip6_ext_hdr RecordVals that includes script-layer
|
* Returns a vector of ip6_ext_hdr RecordVals that includes script-layer
|
||||||
* representation of all extension headers in the chain.
|
* representation of all extension headers in the chain.
|
||||||
|
@ -343,6 +357,13 @@ public:
|
||||||
size_t NumHeaders() const
|
size_t NumHeaders() const
|
||||||
{ return ip4 ? 1 : ip6_hdrs->Size(); }
|
{ return ip4 ? 1 : ip6_hdrs->Size(); }
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns true if this is an IPv6 header containing a routing type 0
|
||||||
|
* extension with nonzero segments left, else returns false.
|
||||||
|
*/
|
||||||
|
bool RH0SegLeft() const
|
||||||
|
{ return ip4 ? false : ip6_hdrs->RH0SegLeft(); }
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns an ip_hdr or ip6_hdr_chain RecordVal.
|
* Returns an ip_hdr or ip6_hdr_chain RecordVal.
|
||||||
*/
|
*/
|
||||||
|
|
|
@ -481,6 +481,22 @@ void NetSessions::DoNextPacket(double t, const struct pcap_pkthdr* hdr,
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Stop analyzing IPv6 packets that use routing type 0 headers with segments
|
||||||
|
// left since RH0 headers are deprecated by RFC 5095 and we'd have to make
|
||||||
|
// extra effort to get the destination in the connection/flow endpoint right.
|
||||||
|
if ( ip_hdr->RH0SegLeft() )
|
||||||
|
{
|
||||||
|
dump_this_packet = 1;
|
||||||
|
if ( rh0_segleft )
|
||||||
|
{
|
||||||
|
val_list* vl = new val_list();
|
||||||
|
vl->append(ip_hdr->BuildPktHdrVal());
|
||||||
|
mgr.QueueEvent(rh0_segleft, vl);
|
||||||
|
}
|
||||||
|
Remove(f);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
int proto = ip_hdr->NextProto();
|
int proto = ip_hdr->NextProto();
|
||||||
|
|
||||||
if ( CheckHeaderTrunc(proto, len, caplen, hdr, pkt) )
|
if ( CheckHeaderTrunc(proto, len, caplen, hdr, pkt) )
|
||||||
|
|
|
@ -478,6 +478,14 @@ event ipv6_ext_headers%(c: connection, p: pkt_hdr%);
|
||||||
## .. bro:see:: new_packet tcp_packet ipv6_ext_headers
|
## .. bro:see:: new_packet tcp_packet ipv6_ext_headers
|
||||||
event esp_packet%(p: pkt_hdr%);
|
event esp_packet%(p: pkt_hdr%);
|
||||||
|
|
||||||
|
## Generated for any packets using an IPv6 Routing Type 0 extension header
|
||||||
|
## with non-zero segments left.
|
||||||
|
##
|
||||||
|
## p: Information from the header of the packet that triggered the event.
|
||||||
|
##
|
||||||
|
## .. bro:see:: new_packet tcp_packet ipv6_ext_headers
|
||||||
|
event rh0_segleft%(p: pkt_hdr%);
|
||||||
|
|
||||||
## Generated for every packet that has non-empty transport-layer payload. This is a
|
## Generated for every packet that has non-empty transport-layer payload. This is a
|
||||||
## very low-level and expensive event that should be avoided when at all possible.
|
## very low-level and expensive event that should be avoided when at all possible.
|
||||||
## It's usually infeasible to handle when processing even medium volumes of
|
## It's usually infeasible to handle when processing even medium volumes of
|
||||||
|
|
|
@ -1 +1 @@
|
||||||
[ip=<uninitialized>, ip6=[class=0, flow=0, len=59, nxt=0, hlim=64, src=2001:4f8:4:7:2e0:81ff:fe52:ffff, dst=2001:4f8:4:7:2e0:81ff:fe52:9a6b, exts=[[id=0, hopopts=[nxt=43, len=0, options=[[otype=1, len=4, data=\0\0\0\0]]], dstopts=<uninitialized>, routing=<uninitialized>, fragment=<uninitialized>, ah=<uninitialized>, esp=<uninitialized>], [id=43, hopopts=<uninitialized>, dstopts=<uninitialized>, routing=[nxt=17, len=4, rtype=0, segleft=2, data=\0\0\0\0 ^A\0x\0^A\02\0\0\0\0\0\0\0^A ^A\0x\0^A\02\0\0\0\0\0\0\0^B], fragment=<uninitialized>, ah=<uninitialized>, esp=<uninitialized>]]], tcp=<uninitialized>, udp=[sport=53/udp, dport=53/udp, ulen=11], icmp=<uninitialized>]
|
[ip=<uninitialized>, ip6=[class=0, flow=0, len=68, nxt=0, hlim=64, src=2001:4f8:4:7:2e0:81ff:fe52:ffff, dst=2001:4f8:4:7:2e0:81ff:fe52:9a6b, exts=[[id=0, hopopts=[nxt=43, len=0, options=[[otype=1, len=4, data=\0\0\0\0]]], dstopts=<uninitialized>, routing=<uninitialized>, fragment=<uninitialized>, ah=<uninitialized>, esp=<uninitialized>], [id=43, hopopts=<uninitialized>, dstopts=<uninitialized>, routing=[nxt=6, len=4, rtype=0, segleft=0, data=\0\0\0\0 ^A\0x\0^A\02\0\0\0\0\0\0\0^A ^A\0x\0^A\02\0\0\0\0\0\0\0^B], fragment=<uninitialized>, ah=<uninitialized>, esp=<uninitialized>]]], tcp=[sport=30000/tcp, dport=80/tcp, seq=0, ack=0, hl=20, dl=0, flags=2, win=8192], udp=<uninitialized>, icmp=<uninitialized>]
|
||||||
|
|
2
testing/btest/Baseline/core.ipv6_rh0/segleft.out
Normal file
2
testing/btest/Baseline/core.ipv6_rh0/segleft.out
Normal file
|
@ -0,0 +1,2 @@
|
||||||
|
flow_weird routing0_segleft from 2001:4f8:4:7:2e0:81ff:fe52:ffff to 2001:78:1:32::2
|
||||||
|
rh0 w/ segments left from 2001:4f8:4:7:2e0:81ff:fe52:ffff to 2001:4f8:4:7:2e0:81ff:fe52:9a6b
|
2
testing/btest/Baseline/core.ipv6_rh0/segleft0.out
Normal file
2
testing/btest/Baseline/core.ipv6_rh0/segleft0.out
Normal file
|
@ -0,0 +1,2 @@
|
||||||
|
flow_weird routing0_header from 2001:4f8:4:7:2e0:81ff:fe52:ffff to 2001:4f8:4:7:2e0:81ff:fe52:9a6b
|
||||||
|
new_connection: [orig_h=2001:4f8:4:7:2e0:81ff:fe52:ffff, orig_p=30000/tcp, resp_h=2001:4f8:4:7:2e0:81ff:fe52:9a6b, resp_p=80/tcp]
|
BIN
testing/btest/Traces/ipv6-hbh-rh0-segleft0.trace
Normal file
BIN
testing/btest/Traces/ipv6-hbh-rh0-segleft0.trace
Normal file
Binary file not shown.
|
@ -1,7 +1,7 @@
|
||||||
# @TEST-EXEC: bro -C -b -r $TRACES/ext_hdr_hbh_routing.trace %INPUT >output
|
# @TEST-EXEC: bro -b -r $TRACES/ipv6-hbh-rh0-segleft.trace %INPUT >output
|
||||||
# @TEST-EXEC: btest-diff output
|
# @TEST-EXEC: btest-diff output
|
||||||
|
|
||||||
event ipv6_ext_headers(c: connection, p: pkt_hdr)
|
event rh0_segleft(p: pkt_hdr)
|
||||||
{
|
{
|
||||||
for ( h in p$ip6$exts )
|
for ( h in p$ip6$exts )
|
||||||
if ( p$ip6$exts[h]$id == IPPROTO_ROUTING )
|
if ( p$ip6$exts[h]$id == IPPROTO_ROUTING )
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
# @TEST-EXEC: bro -C -b -r $TRACES/ext_hdr_hbh_routing.trace %INPUT >output
|
# @TEST-EXEC: bro -b -r $TRACES/ipv6-hbh-rh0-segleft0.trace %INPUT >output
|
||||||
# @TEST-EXEC: btest-diff output
|
# @TEST-EXEC: btest-diff output
|
||||||
|
|
||||||
# Just check that the event is raised correctly for a packet containing
|
# Just check that the event is raised correctly for a packet containing
|
||||||
|
|
22
testing/btest/core/ipv6_rh0.test
Normal file
22
testing/btest/core/ipv6_rh0.test
Normal file
|
@ -0,0 +1,22 @@
|
||||||
|
# @TEST-EXEC: bro -b -r $TRACES/ipv6-hbh-rh0-segleft0.trace %INPUT >segleft0.out
|
||||||
|
# @TEST-EXEC: btest-diff segleft0.out
|
||||||
|
# @TEST-EXEC: bro -b -r $TRACES/ipv6-hbh-rh0-segleft.trace %INPUT >segleft.out
|
||||||
|
# @TEST-EXEC: btest-diff segleft.out
|
||||||
|
|
||||||
|
# This will be raised only by the packet with RH0 and segments left.
|
||||||
|
event rh0_segleft(p: pkt_hdr)
|
||||||
|
{
|
||||||
|
print fmt("rh0 w/ segments left from %s to %s", p$ip6$src, p$ip6$dst);
|
||||||
|
}
|
||||||
|
|
||||||
|
# This will be raised only by the packet with RH0 and no segments left.
|
||||||
|
event new_connection(c: connection)
|
||||||
|
{
|
||||||
|
print fmt("new_connection: %s", c$id);
|
||||||
|
}
|
||||||
|
|
||||||
|
# This will be raised by any packet with RH0 regardless of segments left.
|
||||||
|
event flow_weird(name: string, src: addr, dst: addr)
|
||||||
|
{
|
||||||
|
print fmt("flow_weird %s from %s to %s", name, src, dst);
|
||||||
|
}
|
Loading…
Add table
Add a link
Reference in a new issue