mirror of
https://github.com/zeek/zeek.git
synced 2025-10-14 20:48: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
|
||||
|
||||
* 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);
|
||||
|
||||
// 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;
|
||||
length += len;
|
||||
} while ( current_type != IPPROTO_FRAGMENT &&
|
||||
|
|
21
src/IP.h
21
src/IP.h
|
@ -171,6 +171,20 @@ public:
|
|||
{ return IsFragment() ?
|
||||
(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
|
||||
* representation of all extension headers in the chain.
|
||||
|
@ -343,6 +357,13 @@ public:
|
|||
size_t NumHeaders() const
|
||||
{ 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.
|
||||
*/
|
||||
|
|
|
@ -481,6 +481,22 @@ void NetSessions::DoNextPacket(double t, const struct pcap_pkthdr* hdr,
|
|||
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();
|
||||
|
||||
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
|
||||
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
|
||||
## 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
|
||||
|
|
|
@ -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
|
||||
|
||||
event ipv6_ext_headers(c: connection, p: pkt_hdr)
|
||||
event rh0_segleft(p: pkt_hdr)
|
||||
{
|
||||
for ( h in p$ip6$exts )
|
||||
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
|
||||
|
||||
# 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