mirror of
https://github.com/zeek/zeek.git
synced 2025-10-10 18:48:20 +00:00
Merge remote-tracking branch 'origin/topic/icmp6'
* origin/topic/icmp6: Fixes for IPv6 truncation and ICMP/ICMP6 analysis. Change ICMPv6 checksum calculation to use IP_Hdr wrapper. Update IPv6 atomic fragment unit test to filter output of ICMPv6. Add more data to icmp events More code cleanup Add more icmpv6 events, and general code cleanup Fix compile failure after merge from master Significant edit pass over ICMPv6 code. Porting Matti's branch to git. Closes #808.
This commit is contained in:
commit
5350cab371
60 changed files with 1116 additions and 279 deletions
29
CHANGES
29
CHANGES
|
@ -1,4 +1,33 @@
|
||||||
|
|
||||||
|
2.0-301 | 2012-04-17 17:58:55 -0700
|
||||||
|
|
||||||
|
* Bro now support ICMPv6. (Matti Mantere, Jon Siwek, Robin Sommer,
|
||||||
|
Daniel Thayer).
|
||||||
|
|
||||||
|
Overall, Bro now raises the following ICMP events for v4 and v6 as
|
||||||
|
appropiate:
|
||||||
|
|
||||||
|
event icmp_sent(c: connection, icmp: icmp_conn);
|
||||||
|
event icmp_echo_request(c: connection, icmp: icmp_conn, id: count, seq: count, payload: string);
|
||||||
|
event icmp_echo_reply(c: connection, icmp: icmp_conn, id: count, seq: count, payload: string);
|
||||||
|
event icmp_error_message(c: connection, icmp: icmp_conn, code: count, context: icmp_context);
|
||||||
|
event icmp_unreachable(c: connection, icmp: icmp_conn, code: count, context: icmp_context);
|
||||||
|
event icmp_packet_too_big(c: connection, icmp: icmp_conn, code: count, context: icmp_context);
|
||||||
|
event icmp_time_exceeded(c: connection, icmp: icmp_conn, code: count, context: icmp_context);
|
||||||
|
event icmp_parameter_problem(c: connection, icmp: icmp_conn, code: count, context: icmp_context);
|
||||||
|
event icmp_router_solicitation(c: connection, icmp: icmp_conn);
|
||||||
|
event icmp_router_advertisement(c: connection, icmp: icmp_conn, hop_limit: count, managed: bool, router_lifetime: count, reachable_time: interval, retrans_timer: interval);
|
||||||
|
event icmp_neighbor_solicitation(c: connection, icmp: icmp_conn, tgt:addr);
|
||||||
|
event icmp_neighbor_advertisement(c: connection, icmp: icmp_conn, tgt:addr);
|
||||||
|
event icmp_redirect(c: connection, icmp: icmp_conn, tgt: addr, dest: addr);
|
||||||
|
|
||||||
|
The `icmp_conn` record got a new boolean field 'v6' that indicates
|
||||||
|
whether the ICMP message is v4 or v6.
|
||||||
|
|
||||||
|
This change also includes further low-level work on existing IP
|
||||||
|
and ICMP code, including a reorganization of how ICMPv4 is
|
||||||
|
handled.
|
||||||
|
|
||||||
2.0-281 | 2012-04-17 17:40:39 -0700
|
2.0-281 | 2012-04-17 17:40:39 -0700
|
||||||
|
|
||||||
* Small updates for the bittorrent analyzer to support 64bit types
|
* Small updates for the bittorrent analyzer to support 64bit types
|
||||||
|
|
5
NEWS
5
NEWS
|
@ -43,6 +43,11 @@ Bro 2.1
|
||||||
--enable-perftool-debug to indicate that the switch is only relevant
|
--enable-perftool-debug to indicate that the switch is only relevant
|
||||||
for debugging the heap.
|
for debugging the heap.
|
||||||
|
|
||||||
|
- Bro's ICMP analyzer now handles both IPv4 and IPv6 messages with a
|
||||||
|
joint set of events. The `icmp_conn` record got a new boolean field
|
||||||
|
'v6' that indicates whether the ICMP message is v4 or v6.
|
||||||
|
|
||||||
|
|
||||||
TODO: Extend.
|
TODO: Extend.
|
||||||
|
|
||||||
Bro 2.0
|
Bro 2.0
|
||||||
|
|
2
VERSION
2
VERSION
|
@ -1 +1 @@
|
||||||
2.0-281
|
2.0-301
|
||||||
|
|
|
@ -92,6 +92,7 @@ type icmp_conn: record {
|
||||||
itype: count; ##< The ICMP type of the packet that triggered the instantiation of the record.
|
itype: count; ##< The ICMP type of the packet that triggered the instantiation of the record.
|
||||||
icode: count; ##< The ICMP code of the packet that triggered the instantiation of the record.
|
icode: count; ##< The ICMP code of the packet that triggered the instantiation of the record.
|
||||||
len: count; ##< The length of the ICMP payload of the packet that triggered the instantiation of the record.
|
len: count; ##< The length of the ICMP payload of the packet that triggered the instantiation of the record.
|
||||||
|
v6: bool; ##< True if it's an ICMPv6 packet.
|
||||||
};
|
};
|
||||||
|
|
||||||
## Packet context part of an ICMP message. The fields of this record reflect the
|
## Packet context part of an ICMP message. The fields of this record reflect the
|
||||||
|
@ -100,11 +101,13 @@ type icmp_conn: record {
|
||||||
## .. bro:see:: icmp_time_exceeded icmp_unreachable
|
## .. bro:see:: icmp_time_exceeded icmp_unreachable
|
||||||
type icmp_context: record {
|
type icmp_context: record {
|
||||||
id: conn_id; ##< The packet's 4-tuple.
|
id: conn_id; ##< The packet's 4-tuple.
|
||||||
len: count; ##< The lenght of the packet's IP header.
|
len: count; ##< The length of the IP packet (headers + payload).
|
||||||
proto: count; ##< The packet's transport-layer protocol.
|
proto: count; ##< The packet's transport-layer protocol.
|
||||||
frag_offset: count; ##< The packet's fragementation offset.
|
frag_offset: count; ##< The packet's fragementation offset.
|
||||||
## True if the packet's IP header is fully included in the context. If that is not
|
## True if the packet's IP header is not fully included in the context
|
||||||
## the case, the other fields will all be set to null values.
|
## or if there is not enough of the transport header to determine source
|
||||||
|
## and destination ports. If that is the cast, the appropriate fields
|
||||||
|
## of this record will be set to null values.
|
||||||
bad_hdr_len: bool;
|
bad_hdr_len: bool;
|
||||||
bad_checksum: bool; ##< True if the packet's IP checksum is not correct.
|
bad_checksum: bool; ##< True if the packet's IP checksum is not correct.
|
||||||
MF: bool; ##< True if the packets *more fragements* flag is set.
|
MF: bool; ##< True if the packets *more fragements* flag is set.
|
||||||
|
@ -947,6 +950,7 @@ const IPPROTO_IPIP = 4; ##< IP encapsulation in IP.
|
||||||
const IPPROTO_TCP = 6; ##< TCP.
|
const IPPROTO_TCP = 6; ##< TCP.
|
||||||
const IPPROTO_UDP = 17; ##< User datagram protocol.
|
const IPPROTO_UDP = 17; ##< User datagram protocol.
|
||||||
const IPPROTO_IPV6 = 41; ##< IPv6 header.
|
const IPPROTO_IPV6 = 41; ##< IPv6 header.
|
||||||
|
const IPPROTO_ICMPV6 = 58; ##< ICMP for IPv6.
|
||||||
const IPPROTO_RAW = 255; ##< Raw IP packet.
|
const IPPROTO_RAW = 255; ##< Raw IP packet.
|
||||||
|
|
||||||
# Definitions for IPv6 extension headers.
|
# Definitions for IPv6 extension headers.
|
||||||
|
|
|
@ -49,18 +49,6 @@ const Analyzer::Config Analyzer::analyzer_configs[] = {
|
||||||
|
|
||||||
{ AnalyzerTag::ICMP, "ICMP", ICMP_Analyzer::InstantiateAnalyzer,
|
{ AnalyzerTag::ICMP, "ICMP", ICMP_Analyzer::InstantiateAnalyzer,
|
||||||
ICMP_Analyzer::Available, 0, false },
|
ICMP_Analyzer::Available, 0, false },
|
||||||
{ AnalyzerTag::ICMP_TimeExceeded, "ICMP_TIMEEXCEEDED",
|
|
||||||
ICMP_TimeExceeded_Analyzer::InstantiateAnalyzer,
|
|
||||||
ICMP_TimeExceeded_Analyzer::Available, 0, false },
|
|
||||||
{ AnalyzerTag::ICMP_Unreachable, "ICMP_UNREACHABLE",
|
|
||||||
ICMP_Unreachable_Analyzer::InstantiateAnalyzer,
|
|
||||||
ICMP_Unreachable_Analyzer::Available, 0, false },
|
|
||||||
{ AnalyzerTag::ICMP_Echo, "ICMP_ECHO",
|
|
||||||
ICMP_Echo_Analyzer::InstantiateAnalyzer,
|
|
||||||
ICMP_Echo_Analyzer::Available, 0, false },
|
|
||||||
{ AnalyzerTag::ICMP_Redir, "ICMP_REDIR",
|
|
||||||
ICMP_Redir_Analyzer::InstantiateAnalyzer,
|
|
||||||
ICMP_Redir_Analyzer::Available, 0, false },
|
|
||||||
|
|
||||||
{ AnalyzerTag::TCP, "TCP", TCP_Analyzer::InstantiateAnalyzer,
|
{ AnalyzerTag::TCP, "TCP", TCP_Analyzer::InstantiateAnalyzer,
|
||||||
TCP_Analyzer::Available, 0, false },
|
TCP_Analyzer::Available, 0, false },
|
||||||
|
|
|
@ -20,9 +20,7 @@ namespace AnalyzerTag {
|
||||||
PIA_TCP, PIA_UDP,
|
PIA_TCP, PIA_UDP,
|
||||||
|
|
||||||
// Transport-layer analyzers.
|
// Transport-layer analyzers.
|
||||||
ICMP,
|
ICMP, TCP, UDP,
|
||||||
ICMP_TimeExceeded, ICMP_Unreachable, ICMP_Echo, ICMP_Redir,
|
|
||||||
TCP, UDP,
|
|
||||||
|
|
||||||
// Application-layer analyzers (hand-written).
|
// Application-layer analyzers (hand-written).
|
||||||
BitTorrent, BitTorrentTracker,
|
BitTorrent, BitTorrentTracker,
|
||||||
|
|
42
src/DPM.cc
42
src/DPM.cc
|
@ -185,46 +185,8 @@ bool DPM::BuildInitialAnalyzerTree(TransportProto proto, Connection* conn,
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case TRANSPORT_ICMP: {
|
case TRANSPORT_ICMP: {
|
||||||
const struct icmp* icmpp = (const struct icmp *) data;
|
root = icmp = new ICMP_Analyzer(conn);
|
||||||
switch ( icmpp->icmp_type ) {
|
DBG_DPD(conn, "activated ICMP analyzer");
|
||||||
|
|
||||||
case ICMP_ECHO:
|
|
||||||
case ICMP_ECHOREPLY:
|
|
||||||
if ( ICMP_Echo_Analyzer::Available() )
|
|
||||||
{
|
|
||||||
root = icmp = new ICMP_Echo_Analyzer(conn);
|
|
||||||
DBG_DPD(conn, "activated ICMP Echo analyzer");
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
|
|
||||||
case ICMP_REDIRECT:
|
|
||||||
if ( ICMP_Redir_Analyzer::Available() )
|
|
||||||
{
|
|
||||||
root = new ICMP_Redir_Analyzer(conn);
|
|
||||||
DBG_DPD(conn, "activated ICMP Redir analyzer");
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
|
|
||||||
case ICMP_UNREACH:
|
|
||||||
if ( ICMP_Unreachable_Analyzer::Available() )
|
|
||||||
{
|
|
||||||
root = icmp = new ICMP_Unreachable_Analyzer(conn);
|
|
||||||
DBG_DPD(conn, "activated ICMP Unreachable analyzer");
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
|
|
||||||
case ICMP_TIMXCEED:
|
|
||||||
if ( ICMP_TimeExceeded_Analyzer::Available() )
|
|
||||||
{
|
|
||||||
root = icmp = new ICMP_TimeExceeded_Analyzer(conn);
|
|
||||||
DBG_DPD(conn, "activated ICMP Time Exceeded analyzer");
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
if ( ! root )
|
|
||||||
root = icmp = new ICMP_Analyzer(conn);
|
|
||||||
|
|
||||||
analyzed = true;
|
analyzed = true;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
10
src/Frag.cc
10
src/Frag.cc
|
@ -150,7 +150,7 @@ void FragReassembler::AddFragment(double t, const IP_Hdr* ip, const u_char* pkt)
|
||||||
|
|
||||||
void FragReassembler::Overlap(const u_char* b1, const u_char* b2, int n)
|
void FragReassembler::Overlap(const u_char* b1, const u_char* b2, int n)
|
||||||
{
|
{
|
||||||
IP_Hdr proto_h(proto_hdr, false);
|
IP_Hdr proto_h(proto_hdr, false, proto_hdr_len);
|
||||||
|
|
||||||
if ( memcmp((const void*) b1, (const void*) b2, n) )
|
if ( memcmp((const void*) b1, (const void*) b2, n) )
|
||||||
s->Weird("fragment_inconsistency", &proto_h);
|
s->Weird("fragment_inconsistency", &proto_h);
|
||||||
|
@ -182,7 +182,7 @@ void FragReassembler::BlockInserted(DataBlock* /* start_block */)
|
||||||
// can happen for benign reasons when we're
|
// can happen for benign reasons when we're
|
||||||
// intermingling parts of two fragmented packets.
|
// intermingling parts of two fragmented packets.
|
||||||
|
|
||||||
IP_Hdr proto_h(proto_hdr, false);
|
IP_Hdr proto_h(proto_hdr, false, proto_hdr_len);
|
||||||
s->Weird("fragment_size_inconsistency", &proto_h);
|
s->Weird("fragment_size_inconsistency", &proto_h);
|
||||||
|
|
||||||
// We decide to analyze the contiguous portion now.
|
// We decide to analyze the contiguous portion now.
|
||||||
|
@ -196,7 +196,7 @@ void FragReassembler::BlockInserted(DataBlock* /* start_block */)
|
||||||
|
|
||||||
else if ( last_block->upper > frag_size )
|
else if ( last_block->upper > frag_size )
|
||||||
{
|
{
|
||||||
IP_Hdr proto_h(proto_hdr, false);
|
IP_Hdr proto_h(proto_hdr, false, proto_hdr_len);
|
||||||
s->Weird("fragment_size_inconsistency", &proto_h);
|
s->Weird("fragment_size_inconsistency", &proto_h);
|
||||||
frag_size = last_block->upper;
|
frag_size = last_block->upper;
|
||||||
}
|
}
|
||||||
|
@ -250,8 +250,8 @@ void FragReassembler::BlockInserted(DataBlock* /* start_block */)
|
||||||
{
|
{
|
||||||
struct ip6_hdr* reassem6 = (struct ip6_hdr*) pkt_start;
|
struct ip6_hdr* reassem6 = (struct ip6_hdr*) pkt_start;
|
||||||
reassem6->ip6_plen = htons(frag_size + proto_hdr_len - 40);
|
reassem6->ip6_plen = htons(frag_size + proto_hdr_len - 40);
|
||||||
const IPv6_Hdr_Chain* chain = new IPv6_Hdr_Chain(reassem6, next_proto);
|
const IPv6_Hdr_Chain* chain = new IPv6_Hdr_Chain(reassem6, next_proto, n);
|
||||||
reassembled_pkt = new IP_Hdr(reassem6, true, chain);
|
reassembled_pkt = new IP_Hdr(reassem6, true, n, chain);
|
||||||
}
|
}
|
||||||
|
|
||||||
else
|
else
|
||||||
|
|
555
src/ICMP.cc
555
src/ICMP.cc
|
@ -9,6 +9,8 @@
|
||||||
#include "Event.h"
|
#include "Event.h"
|
||||||
#include "ICMP.h"
|
#include "ICMP.h"
|
||||||
|
|
||||||
|
#include <netinet/icmp6.h>
|
||||||
|
|
||||||
ICMP_Analyzer::ICMP_Analyzer(Connection* c)
|
ICMP_Analyzer::ICMP_Analyzer(Connection* c)
|
||||||
: TransportLayerAnalyzer(AnalyzerTag::ICMP, c)
|
: TransportLayerAnalyzer(AnalyzerTag::ICMP, c)
|
||||||
{
|
{
|
||||||
|
@ -32,7 +34,7 @@ void ICMP_Analyzer::Done()
|
||||||
matcher_state.FinishEndpointMatcher();
|
matcher_state.FinishEndpointMatcher();
|
||||||
}
|
}
|
||||||
|
|
||||||
void ICMP_Analyzer::DeliverPacket(int arg_len, const u_char* data,
|
void ICMP_Analyzer::DeliverPacket(int len, const u_char* data,
|
||||||
bool is_orig, int seq, const IP_Hdr* ip, int caplen)
|
bool is_orig, int seq, const IP_Hdr* ip, int caplen)
|
||||||
{
|
{
|
||||||
assert(ip);
|
assert(ip);
|
||||||
|
@ -46,13 +48,33 @@ void ICMP_Analyzer::DeliverPacket(int arg_len, const u_char* data,
|
||||||
PacketContents(data + 8, min(len, caplen) - 8);
|
PacketContents(data + 8, min(len, caplen) - 8);
|
||||||
|
|
||||||
const struct icmp* icmpp = (const struct icmp*) data;
|
const struct icmp* icmpp = (const struct icmp*) data;
|
||||||
len = arg_len;
|
|
||||||
|
|
||||||
if ( ! ignore_checksums && caplen >= len &&
|
assert(caplen >= len); // Should have been caught earlier already.
|
||||||
icmp_checksum(icmpp, len) != 0xffff )
|
|
||||||
|
if ( ! ignore_checksums )
|
||||||
{
|
{
|
||||||
Weird("bad_ICMP_checksum");
|
int chksum = 0;
|
||||||
return;
|
|
||||||
|
switch ( ip->NextProto() )
|
||||||
|
{
|
||||||
|
case IPPROTO_ICMP:
|
||||||
|
chksum = icmp_checksum(icmpp, len);
|
||||||
|
break;
|
||||||
|
|
||||||
|
case IPPROTO_ICMPV6:
|
||||||
|
chksum = icmp6_checksum(icmpp, ip, len);
|
||||||
|
break;
|
||||||
|
|
||||||
|
default:
|
||||||
|
reporter->InternalError("unexpected IP proto in ICMP analyzer");
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
if ( chksum != 0xffff )
|
||||||
|
{
|
||||||
|
Weird("bad_ICMP_checksum");
|
||||||
|
return;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
Conn()->SetLastTime(current_timestamp);
|
Conn()->SetLastTime(current_timestamp);
|
||||||
|
@ -77,7 +99,13 @@ void ICMP_Analyzer::DeliverPacket(int arg_len, const u_char* data,
|
||||||
else
|
else
|
||||||
len_stat += len;
|
len_stat += len;
|
||||||
|
|
||||||
NextICMP(current_timestamp, icmpp, len, caplen, data);
|
if ( ip->NextProto() == IPPROTO_ICMP )
|
||||||
|
NextICMP4(current_timestamp, icmpp, len, caplen, data, ip);
|
||||||
|
else if ( ip->NextProto() == IPPROTO_ICMPV6 )
|
||||||
|
NextICMP6(current_timestamp, icmpp, len, caplen, data, ip);
|
||||||
|
else
|
||||||
|
reporter->InternalError("unexpected next protocol in ICMP::DeliverPacket()");
|
||||||
|
|
||||||
|
|
||||||
if ( caplen >= len )
|
if ( caplen >= len )
|
||||||
ForwardPacket(len, data, is_orig, seq, ip, caplen);
|
ForwardPacket(len, data, is_orig, seq, ip, caplen);
|
||||||
|
@ -87,26 +115,89 @@ void ICMP_Analyzer::DeliverPacket(int arg_len, const u_char* data,
|
||||||
false, false, true);
|
false, false, true);
|
||||||
}
|
}
|
||||||
|
|
||||||
void ICMP_Analyzer::NextICMP(double /* t */, const struct icmp* /* icmpp */,
|
void ICMP_Analyzer::NextICMP4(double t, const struct icmp* icmpp, int len, int caplen,
|
||||||
int /* len */, int /* caplen */,
|
const u_char*& data, const IP_Hdr* ip_hdr )
|
||||||
const u_char*& /* data */)
|
|
||||||
{
|
{
|
||||||
ICMPEvent(icmp_sent);
|
switch ( icmpp->icmp_type )
|
||||||
|
{
|
||||||
|
case ICMP_ECHO:
|
||||||
|
case ICMP_ECHOREPLY:
|
||||||
|
Echo(t, icmpp, len, caplen, data, ip_hdr);
|
||||||
|
break;
|
||||||
|
|
||||||
|
case ICMP_UNREACH:
|
||||||
|
case ICMP_TIMXCEED:
|
||||||
|
Context4(t, icmpp, len, caplen, data, ip_hdr);
|
||||||
|
break;
|
||||||
|
|
||||||
|
default:
|
||||||
|
ICMPEvent(icmp_sent, icmpp, len, 0);
|
||||||
|
break;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void ICMP_Analyzer::ICMPEvent(EventHandlerPtr f)
|
void ICMP_Analyzer::NextICMP6(double t, const struct icmp* icmpp, int len, int caplen,
|
||||||
|
const u_char*& data, const IP_Hdr* ip_hdr )
|
||||||
{
|
{
|
||||||
|
switch ( icmpp->icmp_type )
|
||||||
|
{
|
||||||
|
// Echo types.
|
||||||
|
case ICMP6_ECHO_REQUEST:
|
||||||
|
case ICMP6_ECHO_REPLY:
|
||||||
|
Echo(t, icmpp, len, caplen, data, ip_hdr);
|
||||||
|
break;
|
||||||
|
|
||||||
|
// Error messages all have the same structure for their context,
|
||||||
|
// and are handled by the same function.
|
||||||
|
case ICMP6_PARAM_PROB:
|
||||||
|
case ICMP6_TIME_EXCEEDED:
|
||||||
|
case ICMP6_PACKET_TOO_BIG:
|
||||||
|
case ICMP6_DST_UNREACH:
|
||||||
|
Context6(t, icmpp, len, caplen, data, ip_hdr);
|
||||||
|
break;
|
||||||
|
|
||||||
|
// Router related messages.
|
||||||
|
case ND_REDIRECT:
|
||||||
|
Redirect(t, icmpp, len, caplen, data, ip_hdr);
|
||||||
|
break;
|
||||||
|
case ND_ROUTER_ADVERT:
|
||||||
|
RouterAdvert(t, icmpp, len, caplen, data, ip_hdr);
|
||||||
|
break;
|
||||||
|
case ND_NEIGHBOR_ADVERT:
|
||||||
|
NeighborAdvert(t, icmpp, len, caplen, data, ip_hdr);
|
||||||
|
break;
|
||||||
|
case ND_NEIGHBOR_SOLICIT:
|
||||||
|
NeighborSolicit(t, icmpp, len, caplen, data, ip_hdr);
|
||||||
|
break;
|
||||||
|
case ND_ROUTER_SOLICIT:
|
||||||
|
case ICMP6_ROUTER_RENUMBERING:
|
||||||
|
Router(t, icmpp, len, caplen, data, ip_hdr);
|
||||||
|
break;
|
||||||
|
|
||||||
|
#if 0
|
||||||
|
// Currently not specifically implemented.
|
||||||
|
case MLD_LISTENER_QUERY:
|
||||||
|
case MLD_LISTENER_REPORT:
|
||||||
|
case MLD_LISTENER_REDUCTION:
|
||||||
|
#endif
|
||||||
|
default:
|
||||||
|
ICMPEvent(icmp_sent, icmpp, len, 1);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void ICMP_Analyzer::ICMPEvent(EventHandlerPtr f, const struct icmp* icmpp, int len, int icmpv6)
|
||||||
|
{
|
||||||
if ( ! f )
|
if ( ! f )
|
||||||
return;
|
return;
|
||||||
|
|
||||||
val_list* vl = new val_list;
|
val_list* vl = new val_list;
|
||||||
vl->append(BuildConnVal());
|
vl->append(BuildConnVal());
|
||||||
vl->append(BuildICMPVal());
|
vl->append(BuildICMPVal(icmpp, len, icmpv6));
|
||||||
|
|
||||||
ConnectionEvent(f, vl);
|
ConnectionEvent(f, vl);
|
||||||
}
|
}
|
||||||
|
|
||||||
RecordVal* ICMP_Analyzer::BuildICMPVal()
|
RecordVal* ICMP_Analyzer::BuildICMPVal(const struct icmp* icmpp, int len, int icmpv6)
|
||||||
{
|
{
|
||||||
if ( ! icmp_conn_val )
|
if ( ! icmp_conn_val )
|
||||||
{
|
{
|
||||||
|
@ -114,9 +205,10 @@ RecordVal* ICMP_Analyzer::BuildICMPVal()
|
||||||
|
|
||||||
icmp_conn_val->Assign(0, new AddrVal(Conn()->OrigAddr()));
|
icmp_conn_val->Assign(0, new AddrVal(Conn()->OrigAddr()));
|
||||||
icmp_conn_val->Assign(1, new AddrVal(Conn()->RespAddr()));
|
icmp_conn_val->Assign(1, new AddrVal(Conn()->RespAddr()));
|
||||||
icmp_conn_val->Assign(2, new Val(type, TYPE_COUNT));
|
icmp_conn_val->Assign(2, new Val(icmpp->icmp_type, TYPE_COUNT));
|
||||||
icmp_conn_val->Assign(3, new Val(code, TYPE_COUNT));
|
icmp_conn_val->Assign(3, new Val(icmpp->icmp_code, TYPE_COUNT));
|
||||||
icmp_conn_val->Assign(4, new Val(len, TYPE_COUNT));
|
icmp_conn_val->Assign(4, new Val(len, TYPE_COUNT));
|
||||||
|
icmp_conn_val->Assign(5, new Val(icmpv6, TYPE_BOOL));
|
||||||
}
|
}
|
||||||
|
|
||||||
Ref(icmp_conn_val);
|
Ref(icmp_conn_val);
|
||||||
|
@ -124,91 +216,115 @@ RecordVal* ICMP_Analyzer::BuildICMPVal()
|
||||||
return icmp_conn_val;
|
return icmp_conn_val;
|
||||||
}
|
}
|
||||||
|
|
||||||
RecordVal* ICMP_Analyzer::ExtractICMPContext(int len, const u_char*& data)
|
TransportProto ICMP_Analyzer::GetContextProtocol(const IP_Hdr* ip_hdr, uint32* src_port, uint32* dst_port)
|
||||||
{
|
{
|
||||||
const struct ip* ip = (const struct ip *) data;
|
const u_char* transport_hdr;
|
||||||
uint32 ip_hdr_len = ip->ip_hl * 4;
|
uint32 ip_hdr_len = ip_hdr->HdrLen();
|
||||||
|
bool ip4 = ip_hdr->IP4_Hdr();
|
||||||
|
|
||||||
|
if ( ip4 )
|
||||||
|
transport_hdr = ((u_char *) ip_hdr->IP4_Hdr() + ip_hdr_len);
|
||||||
|
else
|
||||||
|
transport_hdr = ((u_char *) ip_hdr->IP6_Hdr() + ip_hdr_len);
|
||||||
|
|
||||||
|
TransportProto proto;
|
||||||
|
|
||||||
|
switch ( ip_hdr->NextProto() ) {
|
||||||
|
case 1: proto = TRANSPORT_ICMP; break;
|
||||||
|
case 6: proto = TRANSPORT_TCP; break;
|
||||||
|
case 17: proto = TRANSPORT_UDP; break;
|
||||||
|
case 58: proto = TRANSPORT_ICMP; break;
|
||||||
|
default: proto = TRANSPORT_UNKNOWN; break;
|
||||||
|
}
|
||||||
|
|
||||||
|
switch ( proto ) {
|
||||||
|
case TRANSPORT_ICMP:
|
||||||
|
{
|
||||||
|
const struct icmp* icmpp =
|
||||||
|
(const struct icmp *) transport_hdr;
|
||||||
|
bool is_one_way; // dummy
|
||||||
|
*src_port = ntohs(icmpp->icmp_type);
|
||||||
|
|
||||||
|
if ( ip4 )
|
||||||
|
*dst_port = ntohs(ICMP4_counterpart(icmpp->icmp_type,
|
||||||
|
icmpp->icmp_code, is_one_way));
|
||||||
|
else
|
||||||
|
*dst_port = ntohs(ICMP6_counterpart(icmpp->icmp_type,
|
||||||
|
icmpp->icmp_code, is_one_way));
|
||||||
|
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
case TRANSPORT_TCP:
|
||||||
|
{
|
||||||
|
const struct tcphdr* tp =
|
||||||
|
(const struct tcphdr *) transport_hdr;
|
||||||
|
*src_port = ntohs(tp->th_sport);
|
||||||
|
*dst_port = ntohs(tp->th_dport);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
case TRANSPORT_UDP:
|
||||||
|
{
|
||||||
|
const struct udphdr* up =
|
||||||
|
(const struct udphdr *) transport_hdr;
|
||||||
|
*src_port = ntohs(up->uh_sport);
|
||||||
|
*dst_port = ntohs(up->uh_dport);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
default:
|
||||||
|
*src_port = *dst_port = ntohs(0);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
return proto;
|
||||||
|
}
|
||||||
|
|
||||||
|
RecordVal* ICMP_Analyzer::ExtractICMP4Context(int len, const u_char*& data)
|
||||||
|
{
|
||||||
|
const IP_Hdr ip_hdr_data((const struct ip*) data, false);
|
||||||
|
const IP_Hdr* ip_hdr = &ip_hdr_data;
|
||||||
|
|
||||||
|
uint32 ip_hdr_len = ip_hdr->HdrLen();
|
||||||
|
|
||||||
uint32 ip_len, frag_offset;
|
uint32 ip_len, frag_offset;
|
||||||
TransportProto proto = TRANSPORT_UNKNOWN;
|
TransportProto proto = TRANSPORT_UNKNOWN;
|
||||||
int DF, MF, bad_hdr_len, bad_checksum;
|
int DF, MF, bad_hdr_len, bad_checksum;
|
||||||
uint32 src_addr, dst_addr;
|
IPAddr src_addr, dst_addr;
|
||||||
uint32 src_port, dst_port;
|
uint32 src_port, dst_port;
|
||||||
|
|
||||||
if ( ip_hdr_len < sizeof(struct ip) || ip_hdr_len > uint32(len) )
|
if ( len < (int)sizeof(struct ip) || ip_hdr_len > uint32(len) )
|
||||||
{ // We don't have an entire IP header.
|
{
|
||||||
|
// We don't have an entire IP header.
|
||||||
bad_hdr_len = 1;
|
bad_hdr_len = 1;
|
||||||
ip_len = frag_offset = 0;
|
ip_len = frag_offset = 0;
|
||||||
DF = MF = bad_checksum = 0;
|
DF = MF = bad_checksum = 0;
|
||||||
src_addr = dst_addr = 0;
|
|
||||||
src_port = dst_port = 0;
|
src_port = dst_port = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
bad_hdr_len = 0;
|
bad_hdr_len = 0;
|
||||||
ip_len = ntohs(ip->ip_len);
|
ip_len = ip_hdr->TotalLen();
|
||||||
bad_checksum = ones_complement_checksum((void*) ip, ip_hdr_len, 0) != 0xffff;
|
bad_checksum = (ones_complement_checksum((void*) ip_hdr->IP4_Hdr(), ip_hdr_len, 0) != 0xffff);
|
||||||
|
|
||||||
src_addr = uint32(ip->ip_src.s_addr);
|
src_addr = ip_hdr->SrcAddr();
|
||||||
dst_addr = uint32(ip->ip_dst.s_addr);
|
dst_addr = ip_hdr->DstAddr();
|
||||||
|
|
||||||
switch ( ip->ip_p ) {
|
DF = ip_hdr->DF();
|
||||||
case 1: proto = TRANSPORT_ICMP; break;
|
MF = ip_hdr->MF();
|
||||||
case 6: proto = TRANSPORT_TCP; break;
|
frag_offset = ip_hdr->FragOffset();
|
||||||
case 17: proto = TRANSPORT_UDP; break;
|
|
||||||
|
|
||||||
// Default uses TRANSPORT_UNKNOWN, per initialization above.
|
if ( uint32(len) >= ip_hdr_len + 4 )
|
||||||
}
|
proto = GetContextProtocol(ip_hdr, &src_port, &dst_port);
|
||||||
|
else
|
||||||
uint32 frag_field = ntohs(ip->ip_off);
|
|
||||||
DF = frag_field & 0x4000;
|
|
||||||
MF = frag_field & 0x2000;
|
|
||||||
frag_offset = frag_field & /* IP_OFFMASK not portable */ 0x1fff;
|
|
||||||
const u_char* transport_hdr = ((u_char *) ip + ip_hdr_len);
|
|
||||||
|
|
||||||
if ( uint32(len) < ip_hdr_len + 4 )
|
|
||||||
{
|
{
|
||||||
// 4 above is the magic number meaning that both
|
// 4 above is the magic number meaning that both
|
||||||
// port numbers are included in the ICMP.
|
// port numbers are included in the ICMP.
|
||||||
bad_hdr_len = 1;
|
|
||||||
src_port = dst_port = 0;
|
src_port = dst_port = 0;
|
||||||
|
bad_hdr_len = 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
switch ( proto ) {
|
|
||||||
case TRANSPORT_ICMP:
|
|
||||||
{
|
|
||||||
const struct icmp* icmpp =
|
|
||||||
(const struct icmp *) transport_hdr;
|
|
||||||
bool is_one_way; // dummy
|
|
||||||
src_port = ntohs(icmpp->icmp_type);
|
|
||||||
dst_port = ntohs(ICMP_counterpart(icmpp->icmp_type,
|
|
||||||
icmpp->icmp_code,
|
|
||||||
is_one_way));
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
|
|
||||||
case TRANSPORT_TCP:
|
|
||||||
{
|
|
||||||
const struct tcphdr* tp =
|
|
||||||
(const struct tcphdr *) transport_hdr;
|
|
||||||
src_port = ntohs(tp->th_sport);
|
|
||||||
dst_port = ntohs(tp->th_dport);
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
|
|
||||||
case TRANSPORT_UDP:
|
|
||||||
{
|
|
||||||
const struct udphdr* up =
|
|
||||||
(const struct udphdr *) transport_hdr;
|
|
||||||
src_port = ntohs(up->uh_sport);
|
|
||||||
dst_port = ntohs(up->uh_dport);
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
|
|
||||||
default:
|
|
||||||
src_port = dst_port = ntohs(0);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
RecordVal* iprec = new RecordVal(icmp_context);
|
RecordVal* iprec = new RecordVal(icmp_context);
|
||||||
|
@ -218,8 +334,8 @@ RecordVal* ICMP_Analyzer::ExtractICMPContext(int len, const u_char*& data)
|
||||||
id_val->Assign(1, new PortVal(src_port, proto));
|
id_val->Assign(1, new PortVal(src_port, proto));
|
||||||
id_val->Assign(2, new AddrVal(dst_addr));
|
id_val->Assign(2, new AddrVal(dst_addr));
|
||||||
id_val->Assign(3, new PortVal(dst_port, proto));
|
id_val->Assign(3, new PortVal(dst_port, proto));
|
||||||
iprec->Assign(0, id_val);
|
|
||||||
|
|
||||||
|
iprec->Assign(0, id_val);
|
||||||
iprec->Assign(1, new Val(ip_len, TYPE_COUNT));
|
iprec->Assign(1, new Val(ip_len, TYPE_COUNT));
|
||||||
iprec->Assign(2, new Val(proto, TYPE_COUNT));
|
iprec->Assign(2, new Val(proto, TYPE_COUNT));
|
||||||
iprec->Assign(3, new Val(frag_offset, TYPE_COUNT));
|
iprec->Assign(3, new Val(frag_offset, TYPE_COUNT));
|
||||||
|
@ -231,6 +347,66 @@ RecordVal* ICMP_Analyzer::ExtractICMPContext(int len, const u_char*& data)
|
||||||
return iprec;
|
return iprec;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
RecordVal* ICMP_Analyzer::ExtractICMP6Context(int len, const u_char*& data)
|
||||||
|
{
|
||||||
|
int DF = 0, MF = 0, bad_hdr_len = 0;
|
||||||
|
TransportProto proto = TRANSPORT_UNKNOWN;
|
||||||
|
|
||||||
|
IPAddr src_addr;
|
||||||
|
IPAddr dst_addr;
|
||||||
|
uint32 ip_len, frag_offset = 0;
|
||||||
|
uint32 src_port, dst_port;
|
||||||
|
|
||||||
|
if ( len < (int)sizeof(struct ip6_hdr) )
|
||||||
|
{
|
||||||
|
bad_hdr_len = 1;
|
||||||
|
ip_len = 0;
|
||||||
|
src_port = dst_port = 0;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
const IP_Hdr ip_hdr_data((const struct ip6_hdr*) data, false, len);
|
||||||
|
const IP_Hdr* ip_hdr = &ip_hdr_data;
|
||||||
|
|
||||||
|
ip_len = ip_hdr->TotalLen();
|
||||||
|
src_addr = ip_hdr->SrcAddr();
|
||||||
|
dst_addr = ip_hdr->DstAddr();
|
||||||
|
frag_offset = ip_hdr->FragOffset();
|
||||||
|
MF = ip_hdr->MF();
|
||||||
|
DF = ip_hdr->DF();
|
||||||
|
|
||||||
|
if ( uint32(len) >= uint32(ip_hdr->HdrLen() + 4) )
|
||||||
|
proto = GetContextProtocol(ip_hdr, &src_port, &dst_port);
|
||||||
|
else
|
||||||
|
{
|
||||||
|
// 4 above is the magic number meaning that both
|
||||||
|
// port numbers are included in the ICMP.
|
||||||
|
src_port = dst_port = 0;
|
||||||
|
bad_hdr_len = 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
RecordVal* iprec = new RecordVal(icmp_context);
|
||||||
|
RecordVal* id_val = new RecordVal(conn_id);
|
||||||
|
|
||||||
|
id_val->Assign(0, new AddrVal(src_addr));
|
||||||
|
id_val->Assign(1, new PortVal(src_port, proto));
|
||||||
|
id_val->Assign(2, new AddrVal(dst_addr));
|
||||||
|
id_val->Assign(3, new PortVal(dst_port, proto));
|
||||||
|
|
||||||
|
iprec->Assign(0, id_val);
|
||||||
|
iprec->Assign(1, new Val(ip_len, TYPE_COUNT));
|
||||||
|
iprec->Assign(2, new Val(proto, TYPE_COUNT));
|
||||||
|
iprec->Assign(3, new Val(frag_offset, TYPE_COUNT));
|
||||||
|
iprec->Assign(4, new Val(bad_hdr_len, TYPE_BOOL));
|
||||||
|
// bad_checksum is always false since IPv6 layer doesn't have a checksum.
|
||||||
|
iprec->Assign(5, new Val(0, TYPE_BOOL));
|
||||||
|
iprec->Assign(6, new Val(MF, TYPE_BOOL));
|
||||||
|
iprec->Assign(7, new Val(DF, TYPE_BOOL));
|
||||||
|
|
||||||
|
return iprec;
|
||||||
|
}
|
||||||
|
|
||||||
bool ICMP_Analyzer::IsReuse(double /* t */, const u_char* /* pkt */)
|
bool ICMP_Analyzer::IsReuse(double /* t */, const u_char* /* pkt */)
|
||||||
{
|
{
|
||||||
return 0;
|
return 0;
|
||||||
|
@ -294,15 +470,20 @@ unsigned int ICMP_Analyzer::MemoryAllocation() const
|
||||||
+ (icmp_conn_val ? icmp_conn_val->MemoryAllocation() : 0);
|
+ (icmp_conn_val ? icmp_conn_val->MemoryAllocation() : 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
ICMP_Echo_Analyzer::ICMP_Echo_Analyzer(Connection* c)
|
|
||||||
: ICMP_Analyzer(AnalyzerTag::ICMP_Echo, c)
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
void ICMP_Echo_Analyzer::NextICMP(double t, const struct icmp* icmpp, int len,
|
void ICMP_Analyzer::Echo(double t, const struct icmp* icmpp, int len,
|
||||||
int caplen, const u_char*& data)
|
int caplen, const u_char*& data, const IP_Hdr* ip_hdr)
|
||||||
{
|
{
|
||||||
EventHandlerPtr f = type == ICMP_ECHO ? icmp_echo_request : icmp_echo_reply;
|
// For handling all Echo related ICMP messages
|
||||||
|
EventHandlerPtr f = 0;
|
||||||
|
|
||||||
|
if ( ip_hdr->NextProto() == IPPROTO_ICMPV6 )
|
||||||
|
f = (icmpp->icmp_type == ICMP6_ECHO_REQUEST)
|
||||||
|
? icmp_echo_request : icmp_echo_reply;
|
||||||
|
else
|
||||||
|
f = (icmpp->icmp_type == ICMP_ECHO)
|
||||||
|
? icmp_echo_request : icmp_echo_reply;
|
||||||
|
|
||||||
if ( ! f )
|
if ( ! f )
|
||||||
return;
|
return;
|
||||||
|
|
||||||
|
@ -313,7 +494,7 @@ void ICMP_Echo_Analyzer::NextICMP(double t, const struct icmp* icmpp, int len,
|
||||||
|
|
||||||
val_list* vl = new val_list;
|
val_list* vl = new val_list;
|
||||||
vl->append(BuildConnVal());
|
vl->append(BuildConnVal());
|
||||||
vl->append(BuildICMPVal());
|
vl->append(BuildICMPVal(icmpp, len, ip_hdr->NextProto() != IPPROTO_ICMP));
|
||||||
vl->append(new Val(iid, TYPE_COUNT));
|
vl->append(new Val(iid, TYPE_COUNT));
|
||||||
vl->append(new Val(iseq, TYPE_COUNT));
|
vl->append(new Val(iseq, TYPE_COUNT));
|
||||||
vl->append(new StringVal(payload));
|
vl->append(new StringVal(payload));
|
||||||
|
@ -321,66 +502,224 @@ void ICMP_Echo_Analyzer::NextICMP(double t, const struct icmp* icmpp, int len,
|
||||||
ConnectionEvent(f, vl);
|
ConnectionEvent(f, vl);
|
||||||
}
|
}
|
||||||
|
|
||||||
ICMP_Redir_Analyzer::ICMP_Redir_Analyzer(Connection* c)
|
|
||||||
: ICMP_Analyzer(AnalyzerTag::ICMP_Redir, c)
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
void ICMP_Redir_Analyzer::NextICMP(double t, const struct icmp* icmpp, int len,
|
void ICMP_Analyzer::RouterAdvert(double t, const struct icmp* icmpp, int len,
|
||||||
int caplen, const u_char*& data)
|
int caplen, const u_char*& data, const IP_Hdr* /*ip_hdr*/)
|
||||||
{
|
{
|
||||||
uint32 addr = ntohl(icmpp->icmp_hun.ih_void);
|
EventHandlerPtr f = icmp_router_advertisement;
|
||||||
|
uint32 reachable, retrans;
|
||||||
|
|
||||||
|
memcpy(&reachable, data, sizeof(reachable));
|
||||||
|
memcpy(&retrans, data + sizeof(reachable), sizeof(retrans));
|
||||||
|
|
||||||
val_list* vl = new val_list;
|
val_list* vl = new val_list;
|
||||||
vl->append(BuildConnVal());
|
vl->append(BuildConnVal());
|
||||||
vl->append(BuildICMPVal());
|
vl->append(BuildICMPVal(icmpp, len, 1));
|
||||||
vl->append(new AddrVal(htonl(addr)));
|
vl->append(new Val(icmpp->icmp_num_addrs, TYPE_COUNT));
|
||||||
|
vl->append(new Val(icmpp->icmp_wpa & 0x80, TYPE_BOOL));
|
||||||
|
vl->append(new Val(htons(icmpp->icmp_lifetime), TYPE_COUNT));
|
||||||
|
vl->append(new Val(reachable, TYPE_INTERVAL));
|
||||||
|
vl->append(new Val(retrans, TYPE_INTERVAL));
|
||||||
|
|
||||||
ConnectionEvent(icmp_redirect, vl);
|
ConnectionEvent(f, vl);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void ICMP_Context_Analyzer::NextICMP(double t, const struct icmp* icmpp,
|
void ICMP_Analyzer::NeighborAdvert(double t, const struct icmp* icmpp, int len,
|
||||||
int len, int caplen, const u_char*& data)
|
int caplen, const u_char*& data, const IP_Hdr* /*ip_hdr*/)
|
||||||
|
{
|
||||||
|
EventHandlerPtr f = icmp_neighbor_advertisement;
|
||||||
|
in6_addr tgtaddr;
|
||||||
|
|
||||||
|
memcpy(&tgtaddr.s6_addr, data, sizeof(tgtaddr.s6_addr));
|
||||||
|
|
||||||
|
val_list* vl = new val_list;
|
||||||
|
vl->append(BuildConnVal());
|
||||||
|
vl->append(BuildICMPVal(icmpp, len, 1));
|
||||||
|
vl->append(new AddrVal(IPAddr(tgtaddr)));
|
||||||
|
|
||||||
|
ConnectionEvent(f, vl);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void ICMP_Analyzer::NeighborSolicit(double t, const struct icmp* icmpp, int len,
|
||||||
|
int caplen, const u_char*& data, const IP_Hdr* /*ip_hdr*/)
|
||||||
|
{
|
||||||
|
EventHandlerPtr f = icmp_neighbor_solicitation;
|
||||||
|
in6_addr tgtaddr;
|
||||||
|
|
||||||
|
memcpy(&tgtaddr.s6_addr, data, sizeof(tgtaddr.s6_addr));
|
||||||
|
|
||||||
|
val_list* vl = new val_list;
|
||||||
|
vl->append(BuildConnVal());
|
||||||
|
vl->append(BuildICMPVal(icmpp, len, 1));
|
||||||
|
vl->append(new AddrVal(IPAddr(tgtaddr)));
|
||||||
|
|
||||||
|
ConnectionEvent(f, vl);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void ICMP_Analyzer::Redirect(double t, const struct icmp* icmpp, int len,
|
||||||
|
int caplen, const u_char*& data, const IP_Hdr* /*ip_hdr*/)
|
||||||
|
{
|
||||||
|
EventHandlerPtr f = icmp_redirect;
|
||||||
|
in6_addr tgtaddr, dstaddr;
|
||||||
|
|
||||||
|
memcpy(&tgtaddr.s6_addr, data, sizeof(tgtaddr.s6_addr));
|
||||||
|
memcpy(&dstaddr.s6_addr, data + sizeof(tgtaddr.s6_addr), sizeof(dstaddr.s6_addr));
|
||||||
|
|
||||||
|
val_list* vl = new val_list;
|
||||||
|
vl->append(BuildConnVal());
|
||||||
|
vl->append(BuildICMPVal(icmpp, len, 1));
|
||||||
|
vl->append(new AddrVal(IPAddr(tgtaddr)));
|
||||||
|
vl->append(new AddrVal(IPAddr(dstaddr)));
|
||||||
|
|
||||||
|
ConnectionEvent(f, vl);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void ICMP_Analyzer::Router(double t, const struct icmp* icmpp, int len,
|
||||||
|
int caplen, const u_char*& data, const IP_Hdr* /*ip_hdr*/)
|
||||||
{
|
{
|
||||||
EventHandlerPtr f = 0;
|
EventHandlerPtr f = 0;
|
||||||
switch ( type ) {
|
|
||||||
case ICMP_UNREACH: f = icmp_unreachable; break;
|
switch ( icmpp->icmp_type )
|
||||||
case ICMP_TIMXCEED: f = icmp_time_exceeded; break;
|
{
|
||||||
|
case ND_ROUTER_SOLICIT:
|
||||||
|
f = icmp_router_solicitation;
|
||||||
|
break;
|
||||||
|
case ICMP6_ROUTER_RENUMBERING:
|
||||||
|
default:
|
||||||
|
ICMPEvent(icmp_sent, icmpp, len, 1);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
val_list* vl = new val_list;
|
||||||
|
vl->append(BuildConnVal());
|
||||||
|
vl->append(BuildICMPVal(icmpp, len, 1));
|
||||||
|
|
||||||
|
ConnectionEvent(f, vl);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void ICMP_Analyzer::Context4(double t, const struct icmp* icmpp,
|
||||||
|
int len, int caplen, const u_char*& data, const IP_Hdr* ip_hdr)
|
||||||
|
{
|
||||||
|
EventHandlerPtr f = 0;
|
||||||
|
|
||||||
|
switch ( icmpp->icmp_type )
|
||||||
|
{
|
||||||
|
case ICMP_UNREACH:
|
||||||
|
f = icmp_unreachable;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case ICMP_TIMXCEED:
|
||||||
|
f = icmp_time_exceeded;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
if ( f )
|
if ( f )
|
||||||
{
|
{
|
||||||
val_list* vl = new val_list;
|
val_list* vl = new val_list;
|
||||||
vl->append(BuildConnVal());
|
vl->append(BuildConnVal());
|
||||||
vl->append(BuildICMPVal());
|
vl->append(BuildICMPVal(icmpp, len, 0));
|
||||||
vl->append(new Val(code, TYPE_COUNT));
|
vl->append(new Val(icmpp->icmp_code, TYPE_COUNT));
|
||||||
vl->append(ExtractICMPContext(caplen, data));
|
vl->append(ExtractICMP4Context(caplen, data));
|
||||||
|
|
||||||
ConnectionEvent(f, vl);
|
ConnectionEvent(f, vl);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
int ICMP_counterpart(int icmp_type, int icmp_code, bool& is_one_way)
|
void ICMP_Analyzer::Context6(double t, const struct icmp* icmpp,
|
||||||
|
int len, int caplen, const u_char*& data, const IP_Hdr* ip_hdr)
|
||||||
|
{
|
||||||
|
EventHandlerPtr f = 0;
|
||||||
|
|
||||||
|
switch ( icmpp->icmp_type )
|
||||||
|
{
|
||||||
|
case ICMP6_DST_UNREACH:
|
||||||
|
f = icmp_unreachable;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case ICMP6_PARAM_PROB:
|
||||||
|
f = icmp_parameter_problem;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case ICMP6_TIME_EXCEEDED:
|
||||||
|
f = icmp_time_exceeded;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case ICMP6_PACKET_TOO_BIG:
|
||||||
|
f = icmp_packet_too_big;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
if ( f )
|
||||||
|
{
|
||||||
|
val_list* vl = new val_list;
|
||||||
|
vl->append(BuildConnVal());
|
||||||
|
vl->append(BuildICMPVal(icmpp, len, 1));
|
||||||
|
vl->append(new Val(icmpp->icmp_code, TYPE_COUNT));
|
||||||
|
vl->append(ExtractICMP6Context(caplen, data));
|
||||||
|
ConnectionEvent(f, vl);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
int ICMP4_counterpart(int icmp_type, int icmp_code, bool& is_one_way)
|
||||||
{
|
{
|
||||||
is_one_way = false;
|
is_one_way = false;
|
||||||
|
|
||||||
// return the counterpart type if one exists. This allows us
|
// Return the counterpart type if one exists. This allows us
|
||||||
// to track corresponding ICMP requests/replies.
|
// to track corresponding ICMP requests/replies.
|
||||||
// Note that for the two-way ICMP messages, icmp_code is
|
// Note that for the two-way ICMP messages, icmp_code is
|
||||||
// always 0 (RFC 792).
|
// always 0 (RFC 792).
|
||||||
switch ( icmp_type ) {
|
switch ( icmp_type ) {
|
||||||
case ICMP_ECHO: return ICMP_ECHOREPLY;
|
case ICMP_ECHO: return ICMP_ECHOREPLY;
|
||||||
case ICMP_ECHOREPLY: return ICMP_ECHO;
|
case ICMP_ECHOREPLY: return ICMP_ECHO;
|
||||||
|
|
||||||
case ICMP_TSTAMP: return ICMP_TSTAMPREPLY;
|
case ICMP_TSTAMP: return ICMP_TSTAMPREPLY;
|
||||||
case ICMP_TSTAMPREPLY: return ICMP_TSTAMP;
|
case ICMP_TSTAMPREPLY: return ICMP_TSTAMP;
|
||||||
|
|
||||||
case ICMP_IREQ: return ICMP_IREQREPLY;
|
case ICMP_IREQ: return ICMP_IREQREPLY;
|
||||||
case ICMP_IREQREPLY: return ICMP_IREQ;
|
case ICMP_IREQREPLY: return ICMP_IREQ;
|
||||||
|
|
||||||
case ICMP_ROUTERSOLICIT: return ICMP_ROUTERADVERT;
|
case ICMP_ROUTERSOLICIT: return ICMP_ROUTERADVERT;
|
||||||
|
|
||||||
case ICMP_MASKREQ: return ICMP_MASKREPLY;
|
case ICMP_MASKREQ: return ICMP_MASKREPLY;
|
||||||
case ICMP_MASKREPLY: return ICMP_MASKREQ;
|
case ICMP_MASKREPLY: return ICMP_MASKREQ;
|
||||||
|
|
||||||
default: is_one_way = true; return icmp_code;
|
default: is_one_way = true; return icmp_code;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int ICMP6_counterpart(int icmp_type, int icmp_code, bool& is_one_way)
|
||||||
|
{
|
||||||
|
is_one_way = false;
|
||||||
|
|
||||||
|
switch ( icmp_type ) {
|
||||||
|
case ICMP6_ECHO_REQUEST: return ICMP6_ECHO_REPLY;
|
||||||
|
case ICMP6_ECHO_REPLY: return ICMP6_ECHO_REQUEST;
|
||||||
|
|
||||||
|
case ND_ROUTER_SOLICIT: return ND_ROUTER_ADVERT;
|
||||||
|
case ND_ROUTER_ADVERT: return ND_ROUTER_SOLICIT;
|
||||||
|
|
||||||
|
case ND_NEIGHBOR_SOLICIT: return ND_NEIGHBOR_ADVERT;
|
||||||
|
case ND_NEIGHBOR_ADVERT: return ND_NEIGHBOR_SOLICIT;
|
||||||
|
|
||||||
|
case MLD_LISTENER_QUERY: return MLD_LISTENER_REPORT;
|
||||||
|
case MLD_LISTENER_REPORT: return MLD_LISTENER_QUERY;
|
||||||
|
|
||||||
|
// ICMP node information query and response respectively (not defined in
|
||||||
|
// icmp6.h)
|
||||||
|
case 139: return 140;
|
||||||
|
case 140: return 139;
|
||||||
|
|
||||||
|
// Home Agent Address Discovery Request Message and reply
|
||||||
|
case 144: return 145;
|
||||||
|
case 145: return 144;
|
||||||
|
|
||||||
|
// TODO: Add further counterparts.
|
||||||
|
|
||||||
|
default: is_one_way = true; return icmp_code;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
118
src/ICMP.h
118
src/ICMP.h
|
@ -33,21 +33,49 @@ protected:
|
||||||
virtual bool IsReuse(double t, const u_char* pkt);
|
virtual bool IsReuse(double t, const u_char* pkt);
|
||||||
virtual unsigned int MemoryAllocation() const;
|
virtual unsigned int MemoryAllocation() const;
|
||||||
|
|
||||||
void ICMPEvent(EventHandlerPtr f);
|
void ICMPEvent(EventHandlerPtr f, const struct icmp* icmpp, int len, int icmpv6);
|
||||||
|
|
||||||
|
void Echo(double t, const struct icmp* icmpp, int len,
|
||||||
|
int caplen, const u_char*& data, const IP_Hdr* ip_hdr);
|
||||||
|
void Context(double t, const struct icmp* icmpp, int len,
|
||||||
|
int caplen, const u_char*& data, const IP_Hdr* ip_hdr);
|
||||||
|
void Redirect(double t, const struct icmp* icmpp, int len,
|
||||||
|
int caplen, const u_char*& data, const IP_Hdr* ip_hdr);
|
||||||
|
void RouterAdvert(double t, const struct icmp* icmpp, int len,
|
||||||
|
int caplen, const u_char*& data, const IP_Hdr* ip_hdr);
|
||||||
|
void NeighborAdvert(double t, const struct icmp* icmpp, int len,
|
||||||
|
int caplen, const u_char*& data, const IP_Hdr* ip_hdr);
|
||||||
|
void NeighborSolicit(double t, const struct icmp* icmpp, int len,
|
||||||
|
int caplen, const u_char*& data, const IP_Hdr* ip_hdr);
|
||||||
|
void Router(double t, const struct icmp* icmpp, int len,
|
||||||
|
int caplen, const u_char*& data, const IP_Hdr* ip_hdr);
|
||||||
|
|
||||||
void Describe(ODesc* d) const;
|
void Describe(ODesc* d) const;
|
||||||
|
|
||||||
RecordVal* BuildICMPVal();
|
RecordVal* BuildICMPVal(const struct icmp* icmpp, int len, int icmpv6);
|
||||||
|
|
||||||
virtual void NextICMP(double t, const struct icmp* icmpp,
|
void NextICMP4(double t, const struct icmp* icmpp, int len, int caplen,
|
||||||
int len, int caplen, const u_char*& data);
|
const u_char*& data, const IP_Hdr* ip_hdr );
|
||||||
|
|
||||||
RecordVal* ExtractICMPContext(int len, const u_char*& data);
|
RecordVal* ExtractICMP4Context(int len, const u_char*& data);
|
||||||
|
|
||||||
|
void Context4(double t, const struct icmp* icmpp, int len, int caplen,
|
||||||
|
const u_char*& data, const IP_Hdr* ip_hdr);
|
||||||
|
|
||||||
|
TransportProto GetContextProtocol(const IP_Hdr* ip_hdr, uint32* src_port,
|
||||||
|
uint32* dst_port);
|
||||||
|
|
||||||
|
void NextICMP6(double t, const struct icmp* icmpp, int len, int caplen,
|
||||||
|
const u_char*& data, const IP_Hdr* ip_hdr );
|
||||||
|
|
||||||
|
RecordVal* ExtractICMP6Context(int len, const u_char*& data);
|
||||||
|
|
||||||
|
void Context6(double t, const struct icmp* icmpp, int len, int caplen,
|
||||||
|
const u_char*& data, const IP_Hdr* ip_hdr);
|
||||||
|
|
||||||
RecordVal* icmp_conn_val;
|
RecordVal* icmp_conn_val;
|
||||||
int type;
|
int type;
|
||||||
int code;
|
int code;
|
||||||
int len;
|
|
||||||
|
|
||||||
int request_len, reply_len;
|
int request_len, reply_len;
|
||||||
|
|
||||||
RuleMatcherState matcher_state;
|
RuleMatcherState matcher_state;
|
||||||
|
@ -56,81 +84,9 @@ private:
|
||||||
void UpdateEndpointVal(RecordVal* endp, int is_orig);
|
void UpdateEndpointVal(RecordVal* endp, int is_orig);
|
||||||
};
|
};
|
||||||
|
|
||||||
class ICMP_Echo_Analyzer : public ICMP_Analyzer {
|
|
||||||
public:
|
|
||||||
ICMP_Echo_Analyzer(Connection* conn);
|
|
||||||
|
|
||||||
static Analyzer* InstantiateAnalyzer(Connection* conn)
|
|
||||||
{ return new ICMP_Echo_Analyzer(conn); }
|
|
||||||
|
|
||||||
static bool Available() { return icmp_echo_request || icmp_echo_reply; }
|
|
||||||
|
|
||||||
protected:
|
|
||||||
ICMP_Echo_Analyzer() { }
|
|
||||||
|
|
||||||
virtual void NextICMP(double t, const struct icmp* icmpp,
|
|
||||||
int len, int caplen, const u_char*& data);
|
|
||||||
};
|
|
||||||
|
|
||||||
class ICMP_Redir_Analyzer : public ICMP_Analyzer {
|
|
||||||
public:
|
|
||||||
ICMP_Redir_Analyzer(Connection* conn);
|
|
||||||
|
|
||||||
static Analyzer* InstantiateAnalyzer(Connection* conn)
|
|
||||||
{ return new ICMP_Redir_Analyzer(conn); }
|
|
||||||
|
|
||||||
static bool Available() { return icmp_redirect; }
|
|
||||||
|
|
||||||
protected:
|
|
||||||
ICMP_Redir_Analyzer() { }
|
|
||||||
|
|
||||||
virtual void NextICMP(double t, const struct icmp* icmpp,
|
|
||||||
int len, int caplen, const u_char*& data);
|
|
||||||
};
|
|
||||||
|
|
||||||
class ICMP_Context_Analyzer : public ICMP_Analyzer {
|
|
||||||
public:
|
|
||||||
ICMP_Context_Analyzer(AnalyzerTag::Tag tag, Connection* conn)
|
|
||||||
: ICMP_Analyzer(tag, conn) { }
|
|
||||||
|
|
||||||
protected:
|
|
||||||
ICMP_Context_Analyzer() { }
|
|
||||||
|
|
||||||
virtual void NextICMP(double t, const struct icmp* icmpp,
|
|
||||||
int len, int caplen, const u_char*& data);
|
|
||||||
};
|
|
||||||
|
|
||||||
class ICMP_TimeExceeded_Analyzer : public ICMP_Context_Analyzer {
|
|
||||||
public:
|
|
||||||
ICMP_TimeExceeded_Analyzer(Connection* conn)
|
|
||||||
: ICMP_Context_Analyzer(AnalyzerTag::ICMP_TimeExceeded, conn) { }
|
|
||||||
|
|
||||||
static Analyzer* InstantiateAnalyzer(Connection* conn)
|
|
||||||
{ return new ICMP_TimeExceeded_Analyzer(conn); }
|
|
||||||
|
|
||||||
static bool Available() { return icmp_time_exceeded; }
|
|
||||||
|
|
||||||
protected:
|
|
||||||
ICMP_TimeExceeded_Analyzer() { }
|
|
||||||
};
|
|
||||||
|
|
||||||
class ICMP_Unreachable_Analyzer : public ICMP_Context_Analyzer {
|
|
||||||
public:
|
|
||||||
ICMP_Unreachable_Analyzer(Connection* conn)
|
|
||||||
: ICMP_Context_Analyzer(AnalyzerTag::ICMP_Unreachable, conn) { }
|
|
||||||
|
|
||||||
static Analyzer* InstantiateAnalyzer(Connection* conn)
|
|
||||||
{ return new ICMP_Unreachable_Analyzer(conn); }
|
|
||||||
|
|
||||||
static bool Available() { return icmp_unreachable; }
|
|
||||||
|
|
||||||
protected:
|
|
||||||
ICMP_Unreachable_Analyzer() { }
|
|
||||||
};
|
|
||||||
|
|
||||||
|
|
||||||
// Returns the counterpart type to the given type (e.g., the counterpart
|
// Returns the counterpart type to the given type (e.g., the counterpart
|
||||||
// to ICMP_ECHOREPLY is ICMP_ECHO).
|
// to ICMP_ECHOREPLY is ICMP_ECHO).
|
||||||
extern int ICMP_counterpart(int icmp_type, int icmp_code, bool& is_one_way);
|
extern int ICMP4_counterpart(int icmp_type, int icmp_code, bool& is_one_way);
|
||||||
|
extern int ICMP6_counterpart(int icmp_type, int icmp_code, bool& is_one_way);
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
30
src/IP.cc
30
src/IP.cc
|
@ -419,20 +419,36 @@ static inline bool isIPv6ExtHeader(uint8 type)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void IPv6_Hdr_Chain::Init(const struct ip6_hdr* ip6, bool set_next, uint16 next)
|
void IPv6_Hdr_Chain::Init(const struct ip6_hdr* ip6, int total_len,
|
||||||
|
bool set_next, uint16 next)
|
||||||
{
|
{
|
||||||
length = 0;
|
length = 0;
|
||||||
uint8 current_type, next_type;
|
uint8 current_type, next_type;
|
||||||
next_type = IPPROTO_IPV6;
|
next_type = IPPROTO_IPV6;
|
||||||
const u_char* hdrs = (const u_char*) ip6;
|
const u_char* hdrs = (const u_char*) ip6;
|
||||||
|
|
||||||
|
if ( total_len < (int)sizeof(struct ip6_hdr) )
|
||||||
|
reporter->InternalError("IPv6_HdrChain::Init with truncated IP header");
|
||||||
|
|
||||||
do
|
do
|
||||||
{
|
{
|
||||||
|
// We can't determine a given header's length if there's less than
|
||||||
|
// two bytes of data available (2nd byte of extension headers is length)
|
||||||
|
if ( total_len < 2 )
|
||||||
|
return;
|
||||||
|
|
||||||
current_type = next_type;
|
current_type = next_type;
|
||||||
IPv6_Hdr* p = new IPv6_Hdr(current_type, hdrs);
|
IPv6_Hdr* p = new IPv6_Hdr(current_type, hdrs);
|
||||||
|
|
||||||
next_type = p->NextHdr();
|
next_type = p->NextHdr();
|
||||||
uint16 len = p->Length();
|
uint16 cur_len = p->Length();
|
||||||
|
|
||||||
|
// If this header is truncated, don't add it to chain, don't go further.
|
||||||
|
if ( cur_len > total_len )
|
||||||
|
{
|
||||||
|
delete p;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
if ( set_next && next_type == IPPROTO_FRAGMENT )
|
if ( set_next && next_type == IPPROTO_FRAGMENT )
|
||||||
{
|
{
|
||||||
|
@ -444,16 +460,18 @@ void IPv6_Hdr_Chain::Init(const struct ip6_hdr* ip6, bool set_next, uint16 next)
|
||||||
|
|
||||||
// Check for routing headers and remember final destination address.
|
// Check for routing headers and remember final destination address.
|
||||||
if ( current_type == IPPROTO_ROUTING )
|
if ( current_type == IPPROTO_ROUTING )
|
||||||
ProcessRoutingHeader((const struct ip6_rthdr*) hdrs, len);
|
ProcessRoutingHeader((const struct ip6_rthdr*) hdrs, cur_len);
|
||||||
|
|
||||||
#ifdef ENABLE_MOBILE_IPV6
|
#ifdef ENABLE_MOBILE_IPV6
|
||||||
// Only Mobile IPv6 has a destination option we care about right now.
|
// Only Mobile IPv6 has a destination option we care about right now.
|
||||||
if ( current_type == IPPROTO_DSTOPTS )
|
if ( current_type == IPPROTO_DSTOPTS )
|
||||||
ProcessDstOpts((const struct ip6_dest*) hdrs, len);
|
ProcessDstOpts((const struct ip6_dest*) hdrs, cur_len);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
hdrs += len;
|
hdrs += cur_len;
|
||||||
length += len;
|
length += cur_len;
|
||||||
|
total_len -= cur_len;
|
||||||
|
|
||||||
} while ( current_type != IPPROTO_FRAGMENT &&
|
} while ( current_type != IPPROTO_FRAGMENT &&
|
||||||
current_type != IPPROTO_ESP &&
|
current_type != IPPROTO_ESP &&
|
||||||
#ifdef ENABLE_MOBILE_IPV6
|
#ifdef ENABLE_MOBILE_IPV6
|
||||||
|
|
68
src/IP.h
68
src/IP.h
|
@ -141,12 +141,12 @@ public:
|
||||||
/**
|
/**
|
||||||
* Initializes the header chain from an IPv6 header structure.
|
* Initializes the header chain from an IPv6 header structure.
|
||||||
*/
|
*/
|
||||||
IPv6_Hdr_Chain(const struct ip6_hdr* ip6) :
|
IPv6_Hdr_Chain(const struct ip6_hdr* ip6, int len) :
|
||||||
#ifdef ENABLE_MOBILE_IPV6
|
#ifdef ENABLE_MOBILE_IPV6
|
||||||
homeAddr(0),
|
homeAddr(0),
|
||||||
#endif
|
#endif
|
||||||
finalDst(0)
|
finalDst(0)
|
||||||
{ Init(ip6, false); }
|
{ Init(ip6, len, false); }
|
||||||
|
|
||||||
~IPv6_Hdr_Chain()
|
~IPv6_Hdr_Chain()
|
||||||
{
|
{
|
||||||
|
@ -249,14 +249,20 @@ protected:
|
||||||
* Initializes the header chain from an IPv6 header structure, and replaces
|
* Initializes the header chain from an IPv6 header structure, and replaces
|
||||||
* the first next protocol pointer field that points to a fragment header.
|
* the first next protocol pointer field that points to a fragment header.
|
||||||
*/
|
*/
|
||||||
IPv6_Hdr_Chain(const struct ip6_hdr* ip6, uint16 next) :
|
IPv6_Hdr_Chain(const struct ip6_hdr* ip6, uint16 next, int len) :
|
||||||
#ifdef ENABLE_MOBILE_IPV6
|
#ifdef ENABLE_MOBILE_IPV6
|
||||||
homeAddr(0),
|
homeAddr(0),
|
||||||
#endif
|
#endif
|
||||||
finalDst(0)
|
finalDst(0)
|
||||||
{ Init(ip6, true, next); }
|
{ Init(ip6, len, true, next); }
|
||||||
|
|
||||||
void Init(const struct ip6_hdr* ip6, bool set_next, uint16 next = 0);
|
/**
|
||||||
|
* Initializes the header chain from an IPv6 header structure of a given
|
||||||
|
* length, possibly setting the first next protocol pointer field that
|
||||||
|
* points to a fragment header.
|
||||||
|
*/
|
||||||
|
void Init(const struct ip6_hdr* ip6, int total_len, bool set_next,
|
||||||
|
uint16 next = 0);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Process a routing header and allocate/remember the final destination
|
* Process a routing header and allocate/remember the final destination
|
||||||
|
@ -293,9 +299,21 @@ protected:
|
||||||
IPAddr* finalDst;
|
IPAddr* finalDst;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* A class that wraps either an IPv4 or IPv6 packet and abstracts methods
|
||||||
|
* for inquiring about common features between the two.
|
||||||
|
*/
|
||||||
class IP_Hdr {
|
class IP_Hdr {
|
||||||
public:
|
public:
|
||||||
IP_Hdr(const u_char* p, bool arg_del)
|
/**
|
||||||
|
* Attempts to construct the header from some blob of data based on IP
|
||||||
|
* version number. Caller must have already checked that the header
|
||||||
|
* is not truncated.
|
||||||
|
* @param p pointer to memory containing an IPv4 or IPv6 packet.
|
||||||
|
* @param arg_del whether to take ownership of \a p pointer's memory.
|
||||||
|
* @param len the length of data, in bytes, pointed to by \a p.
|
||||||
|
*/
|
||||||
|
IP_Hdr(const u_char* p, bool arg_del, int len)
|
||||||
: ip4(0), ip6(0), del(arg_del), ip6_hdrs(0)
|
: ip4(0), ip6(0), del(arg_del), ip6_hdrs(0)
|
||||||
{
|
{
|
||||||
if ( ((const struct ip*)p)->ip_v == 4 )
|
if ( ((const struct ip*)p)->ip_v == 4 )
|
||||||
|
@ -303,7 +321,7 @@ public:
|
||||||
else if ( ((const struct ip*)p)->ip_v == 6 )
|
else if ( ((const struct ip*)p)->ip_v == 6 )
|
||||||
{
|
{
|
||||||
ip6 = (const struct ip6_hdr*)p;
|
ip6 = (const struct ip6_hdr*)p;
|
||||||
ip6_hdrs = new IPv6_Hdr_Chain(ip6);
|
ip6_hdrs = new IPv6_Hdr_Chain(ip6, len);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
@ -313,18 +331,38 @@ public:
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Construct the header wrapper from an IPv4 packet. Caller must have
|
||||||
|
* already checked that the header is not truncated.
|
||||||
|
* @param arg_ip4 pointer to memory containing an IPv4 packet.
|
||||||
|
* @param arg_del whether to take ownership of \a arg_ip4 pointer's memory.
|
||||||
|
*/
|
||||||
IP_Hdr(const struct ip* arg_ip4, bool arg_del)
|
IP_Hdr(const struct ip* arg_ip4, bool arg_del)
|
||||||
: ip4(arg_ip4), ip6(0), del(arg_del), ip6_hdrs(0)
|
: ip4(arg_ip4), ip6(0), del(arg_del), ip6_hdrs(0)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
IP_Hdr(const struct ip6_hdr* arg_ip6, bool arg_del,
|
/**
|
||||||
|
* Construct the header wrapper from an IPv6 packet. Caller must have
|
||||||
|
* already checked that the static IPv6 header is not truncated. If
|
||||||
|
* the packet contains extension headers and they are truncated, that can
|
||||||
|
* be checked afterwards by comparing \a len with \a TotalLen. E.g.
|
||||||
|
* NetSessions::DoNextPacket does this to skip truncated packets.
|
||||||
|
* @param arg_ip6 pointer to memory containing an IPv6 packet.
|
||||||
|
* @param arg_del whether to take ownership of \a arg_ip6 pointer's memory.
|
||||||
|
* @param len the packet's length in bytes.
|
||||||
|
* @param c an already-constructed header chain to take ownership of.
|
||||||
|
*/
|
||||||
|
IP_Hdr(const struct ip6_hdr* arg_ip6, bool arg_del, int len,
|
||||||
const IPv6_Hdr_Chain* c = 0)
|
const IPv6_Hdr_Chain* c = 0)
|
||||||
: ip4(0), ip6(arg_ip6), del(arg_del),
|
: ip4(0), ip6(arg_ip6), del(arg_del),
|
||||||
ip6_hdrs(c ? c : new IPv6_Hdr_Chain(ip6))
|
ip6_hdrs(c ? c : new IPv6_Hdr_Chain(ip6, len))
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Destructor.
|
||||||
|
*/
|
||||||
~IP_Hdr()
|
~IP_Hdr()
|
||||||
{
|
{
|
||||||
if ( ip6 )
|
if ( ip6 )
|
||||||
|
@ -339,8 +377,14 @@ public:
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* If an IPv4 packet is wrapped, return a pointer to it, else null.
|
||||||
|
*/
|
||||||
const struct ip* IP4_Hdr() const { return ip4; }
|
const struct ip* IP4_Hdr() const { return ip4; }
|
||||||
|
|
||||||
|
/**
|
||||||
|
* If an IPv6 packet is wrapped, return a pointer to it, else null.
|
||||||
|
*/
|
||||||
const struct ip6_hdr* IP6_Hdr() const { return ip6; }
|
const struct ip6_hdr* IP6_Hdr() const { return ip6; }
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -440,9 +484,15 @@ public:
|
||||||
{ return ip4 ? ip4->ip_p :
|
{ return ip4 ? ip4->ip_p :
|
||||||
((*ip6_hdrs)[ip6_hdrs->Size()-1])->NextHdr(); }
|
((*ip6_hdrs)[ip6_hdrs->Size()-1])->NextHdr(); }
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns the IPv4 Time to Live or IPv6 Hop Limit field.
|
||||||
|
*/
|
||||||
unsigned char TTL() const
|
unsigned char TTL() const
|
||||||
{ return ip4 ? ip4->ip_ttl : ip6->ip6_hlim; }
|
{ return ip4 ? ip4->ip_ttl : ip6->ip6_hlim; }
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns whether the IP header indicates this packet is a fragment.
|
||||||
|
*/
|
||||||
bool IsFragment() const
|
bool IsFragment() const
|
||||||
{ return ip4 ? (ntohs(ip4->ip_off) & 0x3fff) != 0 :
|
{ return ip4 ? (ntohs(ip4->ip_off) & 0x3fff) != 0 :
|
||||||
ip6_hdrs->IsFragment(); }
|
ip6_hdrs->IsFragment(); }
|
||||||
|
|
|
@ -28,8 +28,8 @@ PacketSortElement::PacketSortElement(PktSrc* arg_src,
|
||||||
const struct ip* ip = (const struct ip*) (pkt + hdr_size);
|
const struct ip* ip = (const struct ip*) (pkt + hdr_size);
|
||||||
if ( ip->ip_v == 4 )
|
if ( ip->ip_v == 4 )
|
||||||
ip_hdr = new IP_Hdr(ip, false);
|
ip_hdr = new IP_Hdr(ip, false);
|
||||||
else if ( ip->ip_v == 6 )
|
else if ( ip->ip_v == 6 && (caplen >= sizeof(struct ip6_hdr) + hdr_size) )
|
||||||
ip_hdr = new IP_Hdr((const struct ip6_hdr*) ip, false);
|
ip_hdr = new IP_Hdr((const struct ip6_hdr*) ip, false, caplen - hdr_size);
|
||||||
else
|
else
|
||||||
// Weird will be generated later in NetSessions::NextPacket.
|
// Weird will be generated later in NetSessions::NextPacket.
|
||||||
return;
|
return;
|
||||||
|
|
|
@ -272,6 +272,7 @@ void NetSessions::NextPacket(double t, const struct pcap_pkthdr* hdr,
|
||||||
}
|
}
|
||||||
|
|
||||||
const struct ip* ip = (const struct ip*) (pkt + hdr_size);
|
const struct ip* ip = (const struct ip*) (pkt + hdr_size);
|
||||||
|
|
||||||
if ( ip->ip_v == 4 )
|
if ( ip->ip_v == 4 )
|
||||||
{
|
{
|
||||||
IP_Hdr ip_hdr(ip, false);
|
IP_Hdr ip_hdr(ip, false);
|
||||||
|
@ -280,7 +281,13 @@ void NetSessions::NextPacket(double t, const struct pcap_pkthdr* hdr,
|
||||||
|
|
||||||
else if ( ip->ip_v == 6 )
|
else if ( ip->ip_v == 6 )
|
||||||
{
|
{
|
||||||
IP_Hdr ip_hdr((const struct ip6_hdr*) (pkt + hdr_size), false);
|
if ( caplen < sizeof(struct ip6_hdr) )
|
||||||
|
{
|
||||||
|
Weird("truncated_IP", hdr, pkt);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
IP_Hdr ip_hdr((const struct ip6_hdr*) (pkt + hdr_size), false, caplen);
|
||||||
DoNextPacket(t, hdr, &ip_hdr, pkt, hdr_size);
|
DoNextPacket(t, hdr, &ip_hdr, pkt, hdr_size);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -551,7 +558,23 @@ void NetSessions::DoNextPacket(double t, const struct pcap_pkthdr* hdr,
|
||||||
const struct icmp* icmpp = (const struct icmp *) data;
|
const struct icmp* icmpp = (const struct icmp *) data;
|
||||||
|
|
||||||
id.src_port = icmpp->icmp_type;
|
id.src_port = icmpp->icmp_type;
|
||||||
id.dst_port = ICMP_counterpart(icmpp->icmp_type,
|
id.dst_port = ICMP4_counterpart(icmpp->icmp_type,
|
||||||
|
icmpp->icmp_code,
|
||||||
|
id.is_one_way);
|
||||||
|
|
||||||
|
id.src_port = htons(id.src_port);
|
||||||
|
id.dst_port = htons(id.dst_port);
|
||||||
|
|
||||||
|
d = &icmp_conns;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
case IPPROTO_ICMPV6:
|
||||||
|
{
|
||||||
|
const struct icmp* icmpp = (const struct icmp *) data;
|
||||||
|
|
||||||
|
id.src_port = icmpp->icmp_type;
|
||||||
|
id.dst_port = ICMP6_counterpart(icmpp->icmp_type,
|
||||||
icmpp->icmp_code,
|
icmpp->icmp_code,
|
||||||
id.is_one_way);
|
id.is_one_way);
|
||||||
|
|
||||||
|
@ -669,6 +692,7 @@ bool NetSessions::CheckHeaderTrunc(int proto, uint32 len, uint32 caplen,
|
||||||
min_hdr_len = sizeof(struct udphdr);
|
min_hdr_len = sizeof(struct udphdr);
|
||||||
break;
|
break;
|
||||||
case IPPROTO_ICMP:
|
case IPPROTO_ICMP:
|
||||||
|
case IPPROTO_ICMPV6:
|
||||||
default:
|
default:
|
||||||
// Use for all other packets.
|
// Use for all other packets.
|
||||||
min_hdr_len = ICMP_MINLEN;
|
min_hdr_len = ICMP_MINLEN;
|
||||||
|
@ -998,6 +1022,9 @@ Connection* NetSessions::NewConn(HashKey* k, double t, const ConnID* id,
|
||||||
case IPPROTO_UDP:
|
case IPPROTO_UDP:
|
||||||
tproto = TRANSPORT_UDP;
|
tproto = TRANSPORT_UDP;
|
||||||
break;
|
break;
|
||||||
|
case IPPROTO_ICMPV6:
|
||||||
|
tproto = TRANSPORT_ICMP;
|
||||||
|
break;
|
||||||
default:
|
default:
|
||||||
reporter->InternalError("unknown transport protocol");
|
reporter->InternalError("unknown transport protocol");
|
||||||
break;
|
break;
|
||||||
|
|
|
@ -509,9 +509,9 @@ protected:
|
||||||
#define NUM_PORT_SPACES 4
|
#define NUM_PORT_SPACES 4
|
||||||
#define PORT_SPACE_MASK 0x30000
|
#define PORT_SPACE_MASK 0x30000
|
||||||
|
|
||||||
#define TCP_PORT_MASK 0x10000
|
#define TCP_PORT_MASK 0x10000
|
||||||
#define UDP_PORT_MASK 0x20000
|
#define UDP_PORT_MASK 0x20000
|
||||||
#define ICMP_PORT_MASK 0x30000
|
#define ICMP_PORT_MASK 0x30000
|
||||||
|
|
||||||
class PortVal : public Val {
|
class PortVal : public Val {
|
||||||
public:
|
public:
|
||||||
|
|
126
src/event.bif
126
src/event.bif
|
@ -824,6 +824,24 @@ event icmp_echo_request%(c: connection, icmp: icmp_conn, id: count, seq: count,
|
||||||
## icmp_time_exceeded icmp_unreachable
|
## icmp_time_exceeded icmp_unreachable
|
||||||
event icmp_echo_reply%(c: connection, icmp: icmp_conn, id: count, seq: count, payload: string%);
|
event icmp_echo_reply%(c: connection, icmp: icmp_conn, id: count, seq: count, payload: string%);
|
||||||
|
|
||||||
|
## Generated for all ICMP error messages that are not handled separately with dedicated
|
||||||
|
## ICMP events. Bro's ICMP analyzer handles a number of ICMP messages directly
|
||||||
|
## with dedicated events. This handler acts as a fallback for those it doesn't.
|
||||||
|
## The *icmp* record provides more information about the message.
|
||||||
|
##
|
||||||
|
## See `Wikipedia
|
||||||
|
## <http://en.wikipedia.org/wiki/Internet_Control_Message_Protocol>`__ for more
|
||||||
|
## information about the ICMP protocol.
|
||||||
|
##
|
||||||
|
## c: The connection record for the corresponding ICMP flow.
|
||||||
|
##
|
||||||
|
## icmp: Additional ICMP-specific information augmenting the standard
|
||||||
|
## connection record *c*.
|
||||||
|
##
|
||||||
|
## .. bro:see:: icmp_echo_reply icmp_echo_request icmp_redirect
|
||||||
|
## icmp_time_exceeded icmp_unreachable
|
||||||
|
event icmp_error_message%(c: connection, icmp: icmp_conn, code: count, context: icmp_context%);
|
||||||
|
|
||||||
## Generated for ICMP *destination unreachable* messages.
|
## Generated for ICMP *destination unreachable* messages.
|
||||||
##
|
##
|
||||||
## See `Wikipedia
|
## See `Wikipedia
|
||||||
|
@ -847,6 +865,29 @@ event icmp_echo_reply%(c: connection, icmp: icmp_conn, id: count, seq: count, pa
|
||||||
## icmp_time_exceeded
|
## icmp_time_exceeded
|
||||||
event icmp_unreachable%(c: connection, icmp: icmp_conn, code: count, context: icmp_context%);
|
event icmp_unreachable%(c: connection, icmp: icmp_conn, code: count, context: icmp_context%);
|
||||||
|
|
||||||
|
## Generated for ICMP *packet too big* messages.
|
||||||
|
##
|
||||||
|
## See `Wikipedia
|
||||||
|
## <http://en.wikipedia.org/wiki/Internet_Control_Message_Protocol>`__ for more
|
||||||
|
## information about the ICMP protocol.
|
||||||
|
##
|
||||||
|
## c: The connection record for the corresponding ICMP flow.
|
||||||
|
##
|
||||||
|
## icmp: Additional ICMP-specific information augmenting the standard connection
|
||||||
|
## record *c*.
|
||||||
|
##
|
||||||
|
## code: The ICMP code of the *too big* message.
|
||||||
|
##
|
||||||
|
## context: A record with specifics of the original packet that the message refers
|
||||||
|
## to. *Too big* messages should include the original IP header from the packet
|
||||||
|
## that triggered them, and Bro parses that into the *context* structure. Note
|
||||||
|
## that if the *too big* includes only a partial IP header for some reason, no
|
||||||
|
## fields of *context* will be filled out.
|
||||||
|
##
|
||||||
|
## .. bro:see:: icmp_echo_reply icmp_echo_request icmp_redirect icmp_sent
|
||||||
|
## icmp_time_exceeded
|
||||||
|
event icmp_packet_too_big%(c: connection, icmp: icmp_conn, code: count, context: icmp_context%);
|
||||||
|
|
||||||
## Generated for ICMP *time exceeded* messages.
|
## Generated for ICMP *time exceeded* messages.
|
||||||
##
|
##
|
||||||
## See `Wikipedia
|
## See `Wikipedia
|
||||||
|
@ -870,6 +911,89 @@ event icmp_unreachable%(c: connection, icmp: icmp_conn, code: count, context: ic
|
||||||
## icmp_unreachable
|
## icmp_unreachable
|
||||||
event icmp_time_exceeded%(c: connection, icmp: icmp_conn, code: count, context: icmp_context%);
|
event icmp_time_exceeded%(c: connection, icmp: icmp_conn, code: count, context: icmp_context%);
|
||||||
|
|
||||||
|
## Generated for ICMP *parameter problem* messages.
|
||||||
|
##
|
||||||
|
## See `Wikipedia
|
||||||
|
## <http://en.wikipedia.org/wiki/Internet_Control_Message_Protocol>`__ for more
|
||||||
|
## information about the ICMP protocol.
|
||||||
|
##
|
||||||
|
## c: The connection record for the corresponding ICMP flow.
|
||||||
|
##
|
||||||
|
## icmp: Additional ICMP-specific information augmenting the standard connection
|
||||||
|
## record *c*.
|
||||||
|
##
|
||||||
|
## code: The ICMP code of the *parameter problem* message.
|
||||||
|
##
|
||||||
|
## context: A record with specifics of the original packet that the message refers
|
||||||
|
## to. *Parameter problem* messages should include the original IP header from the packet
|
||||||
|
## that triggered them, and Bro parses that into the *context* structure. Note that
|
||||||
|
## if the *parameter problem* includes only a partial IP header for some reason, no fields
|
||||||
|
## of *context* will be filled out.
|
||||||
|
##
|
||||||
|
## .. bro:see:: icmp_echo_reply icmp_echo_request icmp_redirect icmp_sent
|
||||||
|
## icmp_unreachable
|
||||||
|
event icmp_parameter_problem%(c: connection, icmp: icmp_conn, code: count, context: icmp_context%);
|
||||||
|
|
||||||
|
## Generated for ICMP *router solicitation* messages.
|
||||||
|
##
|
||||||
|
## See `Wikipedia
|
||||||
|
## <http://en.wikipedia.org/wiki/Internet_Control_Message_Protocol>`__ for more
|
||||||
|
## information about the ICMP protocol.
|
||||||
|
##
|
||||||
|
## c: The connection record for the corresponding ICMP flow.
|
||||||
|
##
|
||||||
|
## icmp: Additional ICMP-specific information augmenting the standard connection
|
||||||
|
## record *c*.
|
||||||
|
##
|
||||||
|
## .. bro:see:: icmp_echo_reply icmp_echo_request icmp_sent
|
||||||
|
## icmp_time_exceeded icmp_unreachable
|
||||||
|
event icmp_router_solicitation%(c: connection, icmp: icmp_conn%);
|
||||||
|
|
||||||
|
## Generated for ICMP *router advertisement* messages.
|
||||||
|
##
|
||||||
|
## See `Wikipedia
|
||||||
|
## <http://en.wikipedia.org/wiki/Internet_Control_Message_Protocol>`__ for more
|
||||||
|
## information about the ICMP protocol.
|
||||||
|
##
|
||||||
|
## c: The connection record for the corresponding ICMP flow.
|
||||||
|
##
|
||||||
|
## icmp: Additional ICMP-specific information augmenting the standard connection
|
||||||
|
## record *c*.
|
||||||
|
##
|
||||||
|
## .. bro:see:: icmp_echo_reply icmp_echo_request icmp_sent
|
||||||
|
## icmp_time_exceeded icmp_unreachable
|
||||||
|
event icmp_router_advertisement%(c: connection, icmp: icmp_conn, hop_limit: count, managed: bool, router_lifetime: count, reachable_time: interval, retrans_timer: interval%);
|
||||||
|
|
||||||
|
## Generated for ICMP *neighbor solicitation* messages.
|
||||||
|
##
|
||||||
|
## See `Wikipedia
|
||||||
|
## <http://en.wikipedia.org/wiki/Internet_Control_Message_Protocol>`__ for more
|
||||||
|
## information about the ICMP protocol.
|
||||||
|
##
|
||||||
|
## c: The connection record for the corresponding ICMP flow.
|
||||||
|
##
|
||||||
|
## icmp: Additional ICMP-specific information augmenting the standard connection
|
||||||
|
## record *c*.
|
||||||
|
##
|
||||||
|
## .. bro:see:: icmp_echo_reply icmp_echo_request icmp_sent
|
||||||
|
## icmp_time_exceeded icmp_unreachable
|
||||||
|
event icmp_neighbor_solicitation%(c: connection, icmp: icmp_conn, tgt:addr%);
|
||||||
|
|
||||||
|
## Generated for ICMP *neighbor advertisement* messages.
|
||||||
|
##
|
||||||
|
## See `Wikipedia
|
||||||
|
## <http://en.wikipedia.org/wiki/Internet_Control_Message_Protocol>`__ for more
|
||||||
|
## information about the ICMP protocol.
|
||||||
|
##
|
||||||
|
## c: The connection record for the corresponding ICMP flow.
|
||||||
|
##
|
||||||
|
## icmp: Additional ICMP-specific information augmenting the standard connection
|
||||||
|
## record *c*.
|
||||||
|
##
|
||||||
|
## .. bro:see:: icmp_echo_reply icmp_echo_request icmp_sent
|
||||||
|
## icmp_time_exceeded icmp_unreachable
|
||||||
|
event icmp_neighbor_advertisement%(c: connection, icmp: icmp_conn, tgt:addr%);
|
||||||
|
|
||||||
## Generated for ICMP *redirect* messages.
|
## Generated for ICMP *redirect* messages.
|
||||||
##
|
##
|
||||||
## See `Wikipedia
|
## See `Wikipedia
|
||||||
|
@ -885,7 +1009,7 @@ event icmp_time_exceeded%(c: connection, icmp: icmp_conn, code: count, context:
|
||||||
##
|
##
|
||||||
## .. bro:see:: icmp_echo_reply icmp_echo_request icmp_sent
|
## .. bro:see:: icmp_echo_reply icmp_echo_request icmp_sent
|
||||||
## icmp_time_exceeded icmp_unreachable
|
## icmp_time_exceeded icmp_unreachable
|
||||||
event icmp_redirect%(c: connection, icmp: icmp_conn, a: addr%);
|
event icmp_redirect%(c: connection, icmp: icmp_conn, tgt: addr, dest: addr%);
|
||||||
|
|
||||||
## Generated when a TCP connection terminated, passing on statistics about the
|
## Generated when a TCP connection terminated, passing on statistics about the
|
||||||
## two endpoints. This event is always generated when Bro flushes the internal
|
## two endpoints. This event is always generated when Bro flushes the internal
|
||||||
|
|
|
@ -80,6 +80,33 @@ int mobility_header_checksum(const IP_Hdr* ip)
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
int icmp6_checksum(const struct icmp* icmpp, const IP_Hdr* ip, int len)
|
||||||
|
{
|
||||||
|
// ICMP6 uses the same checksum function as ICMP4 but a different
|
||||||
|
// pseudo-header over which it is computed.
|
||||||
|
uint32 sum;
|
||||||
|
|
||||||
|
if ( len % 2 == 1 )
|
||||||
|
// Add in pad byte.
|
||||||
|
sum = htons(((const u_char*) icmpp)[len - 1] << 8);
|
||||||
|
else
|
||||||
|
sum = 0;
|
||||||
|
|
||||||
|
// Pseudo-header as for UDP over IPv6 above.
|
||||||
|
sum = ones_complement_checksum(ip->SrcAddr(), sum);
|
||||||
|
sum = ones_complement_checksum(ip->DstAddr(), sum);
|
||||||
|
uint32 l = htonl(len);
|
||||||
|
sum = ones_complement_checksum((void*) &l, 4, sum);
|
||||||
|
|
||||||
|
uint32 addl_pseudo = htons(IPPROTO_ICMPV6);
|
||||||
|
sum = ones_complement_checksum((void*) &addl_pseudo, 4, sum);
|
||||||
|
|
||||||
|
sum = ones_complement_checksum((void*) icmpp, len, sum);
|
||||||
|
|
||||||
|
return sum;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
#define CLASS_A 0x00000000
|
#define CLASS_A 0x00000000
|
||||||
#define CLASS_B 0x80000000
|
#define CLASS_B 0x80000000
|
||||||
#define CLASS_C 0xc0000000
|
#define CLASS_C 0xc0000000
|
||||||
|
|
|
@ -134,16 +134,17 @@ inline int seq_delta(uint32 a, uint32 b)
|
||||||
}
|
}
|
||||||
|
|
||||||
class IPAddr;
|
class IPAddr;
|
||||||
|
class IP_Hdr;
|
||||||
|
|
||||||
// Returns the ones-complement checksum of a chunk of b short-aligned bytes.
|
// Returns the ones-complement checksum of a chunk of b short-aligned bytes.
|
||||||
extern int ones_complement_checksum(const void* p, int b, uint32 sum);
|
extern int ones_complement_checksum(const void* p, int b, uint32 sum);
|
||||||
|
|
||||||
extern int ones_complement_checksum(const IPAddr& a, uint32 sum);
|
extern int ones_complement_checksum(const IPAddr& a, uint32 sum);
|
||||||
|
|
||||||
|
extern int icmp6_checksum(const struct icmp* icmpp, const IP_Hdr* ip, int len);
|
||||||
extern int icmp_checksum(const struct icmp* icmpp, int len);
|
extern int icmp_checksum(const struct icmp* icmpp, int len);
|
||||||
|
|
||||||
#ifdef ENABLE_MOBILE_IPV6
|
#ifdef ENABLE_MOBILE_IPV6
|
||||||
class IP_Hdr;
|
|
||||||
extern int mobility_header_checksum(const IP_Hdr* ip);
|
extern int mobility_header_checksum(const IP_Hdr* ip);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|
|
@ -1,9 +1,13 @@
|
||||||
1332784981.078396 weird: bad_IP_checksum
|
1332784981.078396 weird: bad_IP_checksum
|
||||||
1332784885.686428 weird: bad_TCP_checksum
|
1332784885.686428 weird: bad_TCP_checksum
|
||||||
1332784933.501023 weird: bad_UDP_checksum
|
1332784933.501023 weird: bad_UDP_checksum
|
||||||
|
1334075363.536871 weird: bad_ICMP_checksum
|
||||||
1332785210.013051 weird: routing0_hdr
|
1332785210.013051 weird: routing0_hdr
|
||||||
1332785210.013051 weird: bad_TCP_checksum
|
1332785210.013051 weird: bad_TCP_checksum
|
||||||
1332782580.798420 weird: routing0_hdr
|
1332782580.798420 weird: routing0_hdr
|
||||||
1332782580.798420 weird: bad_UDP_checksum
|
1332782580.798420 weird: bad_UDP_checksum
|
||||||
|
1334075111.800086 weird: routing0_hdr
|
||||||
|
1334075111.800086 weird: bad_ICMP_checksum
|
||||||
1332785250.469132 weird: bad_TCP_checksum
|
1332785250.469132 weird: bad_TCP_checksum
|
||||||
1332781342.923813 weird: bad_UDP_checksum
|
1332781342.923813 weird: bad_UDP_checksum
|
||||||
|
1334074939.467194 weird: bad_ICMP_checksum
|
||||||
|
|
|
@ -1,2 +1,3 @@
|
||||||
1332785125.596793 weird: routing0_hdr
|
1332785125.596793 weird: routing0_hdr
|
||||||
1332782508.592037 weird: routing0_hdr
|
1332782508.592037 weird: routing0_hdr
|
||||||
|
1334075027.053380 weird: routing0_hdr
|
||||||
|
|
12
testing/btest/Baseline/core.icmp.icmp-context/output
Normal file
12
testing/btest/Baseline/core.icmp.icmp-context/output
Normal file
|
@ -0,0 +1,12 @@
|
||||||
|
icmp_unreachable (code=0)
|
||||||
|
conn_id: [orig_h=10.0.0.1, orig_p=3/icmp, resp_h=10.0.0.2, resp_p=0/icmp]
|
||||||
|
icmp_conn: [orig_h=10.0.0.1, resp_h=10.0.0.2, itype=3, icode=0, len=0, v6=F]
|
||||||
|
icmp_context: [id=[orig_h=::, orig_p=0/unknown, resp_h=::, resp_p=0/unknown], len=0, proto=0, frag_offset=0, bad_hdr_len=T, bad_checksum=F, MF=F, DF=F]
|
||||||
|
icmp_unreachable (code=0)
|
||||||
|
conn_id: [orig_h=10.0.0.1, orig_p=3/icmp, resp_h=10.0.0.2, resp_p=0/icmp]
|
||||||
|
icmp_conn: [orig_h=10.0.0.1, resp_h=10.0.0.2, itype=3, icode=0, len=20, v6=F]
|
||||||
|
icmp_context: [id=[orig_h=10.0.0.2, orig_p=0/unknown, resp_h=10.0.0.1, resp_p=0/unknown], len=20, proto=0, frag_offset=0, bad_hdr_len=T, bad_checksum=F, MF=F, DF=F]
|
||||||
|
icmp_unreachable (code=3)
|
||||||
|
conn_id: [orig_h=192.168.1.102, orig_p=3/icmp, resp_h=192.168.1.1, resp_p=3/icmp]
|
||||||
|
icmp_conn: [orig_h=192.168.1.102, resp_h=192.168.1.1, itype=3, icode=3, len=148, v6=F]
|
||||||
|
icmp_context: [id=[orig_h=192.168.1.1, orig_p=53/udp, resp_h=192.168.1.102, resp_p=59207/udp], len=163, proto=2, frag_offset=0, bad_hdr_len=F, bad_checksum=F, MF=F, DF=F]
|
20
testing/btest/Baseline/core.icmp.icmp-events/output
Normal file
20
testing/btest/Baseline/core.icmp.icmp-events/output
Normal file
|
@ -0,0 +1,20 @@
|
||||||
|
icmp_unreachable (code=3)
|
||||||
|
conn_id: [orig_h=192.168.1.102, orig_p=3/icmp, resp_h=192.168.1.1, resp_p=3/icmp]
|
||||||
|
icmp_conn: [orig_h=192.168.1.102, resp_h=192.168.1.1, itype=3, icode=3, len=148, v6=F]
|
||||||
|
icmp_context: [id=[orig_h=192.168.1.1, orig_p=53/udp, resp_h=192.168.1.102, resp_p=59207/udp], len=163, proto=2, frag_offset=0, bad_hdr_len=F, bad_checksum=F, MF=F, DF=F]
|
||||||
|
icmp_time_exceeded (code=0)
|
||||||
|
conn_id: [orig_h=10.0.0.1, orig_p=11/icmp, resp_h=10.0.0.2, resp_p=0/icmp]
|
||||||
|
icmp_conn: [orig_h=10.0.0.1, resp_h=10.0.0.2, itype=11, icode=0, len=32, v6=F]
|
||||||
|
icmp_context: [id=[orig_h=10.0.0.2, orig_p=30000/udp, resp_h=10.0.0.1, resp_p=13000/udp], len=32, proto=2, frag_offset=0, bad_hdr_len=F, bad_checksum=F, MF=F, DF=F]
|
||||||
|
icmp_echo_request (id=34844, seq=0, payload=O\x85\xe0C\0^N\xeb\xff^H^I^J^K^L^M^N^O^P^Q^R^S^T^U^V^W^X^Y^Z\x1b\x1c\x1d\x1e\x1f !"#$%&'()*+,-./01234567)
|
||||||
|
conn_id: [orig_h=10.0.0.1, orig_p=8/icmp, resp_h=74.125.225.99, resp_p=0/icmp]
|
||||||
|
icmp_conn: [orig_h=10.0.0.1, resp_h=74.125.225.99, itype=8, icode=0, len=56, v6=F]
|
||||||
|
icmp_echo_reply (id=34844, seq=0, payload=O\x85\xe0C\0^N\xeb\xff^H^I^J^K^L^M^N^O^P^Q^R^S^T^U^V^W^X^Y^Z\x1b\x1c\x1d\x1e\x1f !"#$%&'()*+,-./01234567)
|
||||||
|
conn_id: [orig_h=10.0.0.1, orig_p=8/icmp, resp_h=74.125.225.99, resp_p=0/icmp]
|
||||||
|
icmp_conn: [orig_h=10.0.0.1, resp_h=74.125.225.99, itype=8, icode=0, len=56, v6=F]
|
||||||
|
icmp_echo_request (id=34844, seq=1, payload=O\x85\xe0D\0^N\xf0}^H^I^J^K^L^M^N^O^P^Q^R^S^T^U^V^W^X^Y^Z\x1b\x1c\x1d\x1e\x1f !"#$%&'()*+,-./01234567)
|
||||||
|
conn_id: [orig_h=10.0.0.1, orig_p=8/icmp, resp_h=74.125.225.99, resp_p=0/icmp]
|
||||||
|
icmp_conn: [orig_h=10.0.0.1, resp_h=74.125.225.99, itype=8, icode=0, len=56, v6=F]
|
||||||
|
icmp_echo_reply (id=34844, seq=1, payload=O\x85\xe0D\0^N\xf0}^H^I^J^K^L^M^N^O^P^Q^R^S^T^U^V^W^X^Y^Z\x1b\x1c\x1d\x1e\x1f !"#$%&'()*+,-./01234567)
|
||||||
|
conn_id: [orig_h=10.0.0.1, orig_p=8/icmp, resp_h=74.125.225.99, resp_p=0/icmp]
|
||||||
|
icmp_conn: [orig_h=10.0.0.1, resp_h=74.125.225.99, itype=8, icode=0, len=56, v6=F]
|
16
testing/btest/Baseline/core.icmp.icmp6-context/output
Normal file
16
testing/btest/Baseline/core.icmp.icmp6-context/output
Normal file
|
@ -0,0 +1,16 @@
|
||||||
|
icmp_unreachable (code=0)
|
||||||
|
conn_id: [orig_h=fe80::dead, orig_p=1/icmp, resp_h=fe80::beef, resp_p=0/icmp]
|
||||||
|
icmp_conn: [orig_h=fe80::dead, resp_h=fe80::beef, itype=1, icode=0, len=0, v6=T]
|
||||||
|
icmp_context: [id=[orig_h=::, orig_p=0/unknown, resp_h=::, resp_p=0/unknown], len=0, proto=0, frag_offset=0, bad_hdr_len=T, bad_checksum=F, MF=F, DF=F]
|
||||||
|
icmp_unreachable (code=0)
|
||||||
|
conn_id: [orig_h=fe80::dead, orig_p=1/icmp, resp_h=fe80::beef, resp_p=0/icmp]
|
||||||
|
icmp_conn: [orig_h=fe80::dead, resp_h=fe80::beef, itype=1, icode=0, len=40, v6=T]
|
||||||
|
icmp_context: [id=[orig_h=fe80::beef, orig_p=0/unknown, resp_h=fe80::dead, resp_p=0/unknown], len=48, proto=0, frag_offset=0, bad_hdr_len=T, bad_checksum=F, MF=F, DF=F]
|
||||||
|
icmp_unreachable (code=0)
|
||||||
|
conn_id: [orig_h=fe80::dead, orig_p=1/icmp, resp_h=fe80::beef, resp_p=0/icmp]
|
||||||
|
icmp_conn: [orig_h=fe80::dead, resp_h=fe80::beef, itype=1, icode=0, len=60, v6=T]
|
||||||
|
icmp_context: [id=[orig_h=fe80::beef, orig_p=30000/udp, resp_h=fe80::dead, resp_p=13000/udp], len=60, proto=2, frag_offset=0, bad_hdr_len=F, bad_checksum=F, MF=F, DF=F]
|
||||||
|
icmp_unreachable (code=0)
|
||||||
|
conn_id: [orig_h=fe80::dead, orig_p=1/icmp, resp_h=fe80::beef, resp_p=0/icmp]
|
||||||
|
icmp_conn: [orig_h=fe80::dead, resp_h=fe80::beef, itype=1, icode=0, len=48, v6=T]
|
||||||
|
icmp_context: [id=[orig_h=fe80::beef, orig_p=0/unknown, resp_h=fe80::dead, resp_p=0/unknown], len=48, proto=0, frag_offset=0, bad_hdr_len=T, bad_checksum=F, MF=F, DF=F]
|
55
testing/btest/Baseline/core.icmp.icmp6-events/output
Normal file
55
testing/btest/Baseline/core.icmp.icmp6-events/output
Normal file
|
@ -0,0 +1,55 @@
|
||||||
|
icmp_unreachable (code=0)
|
||||||
|
conn_id: [orig_h=fe80::dead, orig_p=1/icmp, resp_h=fe80::beef, resp_p=0/icmp]
|
||||||
|
icmp_conn: [orig_h=fe80::dead, resp_h=fe80::beef, itype=1, icode=0, len=60, v6=T]
|
||||||
|
icmp_context: [id=[orig_h=fe80::beef, orig_p=30000/udp, resp_h=fe80::dead, resp_p=13000/udp], len=60, proto=2, frag_offset=0, bad_hdr_len=F, bad_checksum=F, MF=F, DF=F]
|
||||||
|
icmp_packet_too_big (code=0)
|
||||||
|
conn_id: [orig_h=fe80::dead, orig_p=2/icmp, resp_h=fe80::beef, resp_p=0/icmp]
|
||||||
|
icmp_conn: [orig_h=fe80::dead, resp_h=fe80::beef, itype=2, icode=0, len=52, v6=T]
|
||||||
|
icmp_context: [id=[orig_h=fe80::beef, orig_p=30000/udp, resp_h=fe80::dead, resp_p=13000/udp], len=52, proto=2, frag_offset=0, bad_hdr_len=F, bad_checksum=F, MF=F, DF=F]
|
||||||
|
icmp_time_exceeded (code=0)
|
||||||
|
conn_id: [orig_h=fe80::dead, orig_p=3/icmp, resp_h=fe80::beef, resp_p=0/icmp]
|
||||||
|
icmp_conn: [orig_h=fe80::dead, resp_h=fe80::beef, itype=3, icode=0, len=52, v6=T]
|
||||||
|
icmp_context: [id=[orig_h=fe80::beef, orig_p=30000/udp, resp_h=fe80::dead, resp_p=13000/udp], len=52, proto=2, frag_offset=0, bad_hdr_len=F, bad_checksum=F, MF=F, DF=F]
|
||||||
|
icmp_parameter_problem (code=0)
|
||||||
|
conn_id: [orig_h=fe80::dead, orig_p=4/icmp, resp_h=fe80::beef, resp_p=0/icmp]
|
||||||
|
icmp_conn: [orig_h=fe80::dead, resp_h=fe80::beef, itype=4, icode=0, len=52, v6=T]
|
||||||
|
icmp_context: [id=[orig_h=fe80::beef, orig_p=30000/udp, resp_h=fe80::dead, resp_p=13000/udp], len=52, proto=2, frag_offset=0, bad_hdr_len=F, bad_checksum=F, MF=F, DF=F]
|
||||||
|
icmp_echo_request (id=1, seq=3, payload=abcdefghijklmnopqrstuvwabcdefghi)
|
||||||
|
conn_id: [orig_h=2620:0:e00:400e:d1d:db37:beb:5aac, orig_p=128/icmp, resp_h=2001:4860:8006::63, resp_p=129/icmp]
|
||||||
|
icmp_conn: [orig_h=2620:0:e00:400e:d1d:db37:beb:5aac, resp_h=2001:4860:8006::63, itype=128, icode=0, len=32, v6=T]
|
||||||
|
icmp_echo_reply (id=1, seq=3, payload=abcdefghijklmnopqrstuvwabcdefghi)
|
||||||
|
conn_id: [orig_h=2620:0:e00:400e:d1d:db37:beb:5aac, orig_p=128/icmp, resp_h=2001:4860:8006::63, resp_p=129/icmp]
|
||||||
|
icmp_conn: [orig_h=2620:0:e00:400e:d1d:db37:beb:5aac, resp_h=2001:4860:8006::63, itype=128, icode=0, len=32, v6=T]
|
||||||
|
icmp_echo_request (id=1, seq=4, payload=abcdefghijklmnopqrstuvwabcdefghi)
|
||||||
|
conn_id: [orig_h=2620:0:e00:400e:d1d:db37:beb:5aac, orig_p=128/icmp, resp_h=2001:4860:8006::63, resp_p=129/icmp]
|
||||||
|
icmp_conn: [orig_h=2620:0:e00:400e:d1d:db37:beb:5aac, resp_h=2001:4860:8006::63, itype=128, icode=0, len=32, v6=T]
|
||||||
|
icmp_echo_reply (id=1, seq=4, payload=abcdefghijklmnopqrstuvwabcdefghi)
|
||||||
|
conn_id: [orig_h=2620:0:e00:400e:d1d:db37:beb:5aac, orig_p=128/icmp, resp_h=2001:4860:8006::63, resp_p=129/icmp]
|
||||||
|
icmp_conn: [orig_h=2620:0:e00:400e:d1d:db37:beb:5aac, resp_h=2001:4860:8006::63, itype=128, icode=0, len=32, v6=T]
|
||||||
|
icmp_echo_request (id=1, seq=5, payload=abcdefghijklmnopqrstuvwabcdefghi)
|
||||||
|
conn_id: [orig_h=2620:0:e00:400e:d1d:db37:beb:5aac, orig_p=128/icmp, resp_h=2001:4860:8006::63, resp_p=129/icmp]
|
||||||
|
icmp_conn: [orig_h=2620:0:e00:400e:d1d:db37:beb:5aac, resp_h=2001:4860:8006::63, itype=128, icode=0, len=32, v6=T]
|
||||||
|
icmp_echo_reply (id=1, seq=5, payload=abcdefghijklmnopqrstuvwabcdefghi)
|
||||||
|
conn_id: [orig_h=2620:0:e00:400e:d1d:db37:beb:5aac, orig_p=128/icmp, resp_h=2001:4860:8006::63, resp_p=129/icmp]
|
||||||
|
icmp_conn: [orig_h=2620:0:e00:400e:d1d:db37:beb:5aac, resp_h=2001:4860:8006::63, itype=128, icode=0, len=32, v6=T]
|
||||||
|
icmp_echo_request (id=1, seq=6, payload=abcdefghijklmnopqrstuvwabcdefghi)
|
||||||
|
conn_id: [orig_h=2620:0:e00:400e:d1d:db37:beb:5aac, orig_p=128/icmp, resp_h=2001:4860:8006::63, resp_p=129/icmp]
|
||||||
|
icmp_conn: [orig_h=2620:0:e00:400e:d1d:db37:beb:5aac, resp_h=2001:4860:8006::63, itype=128, icode=0, len=32, v6=T]
|
||||||
|
icmp_echo_reply (id=1, seq=6, payload=abcdefghijklmnopqrstuvwabcdefghi)
|
||||||
|
conn_id: [orig_h=2620:0:e00:400e:d1d:db37:beb:5aac, orig_p=128/icmp, resp_h=2001:4860:8006::63, resp_p=129/icmp]
|
||||||
|
icmp_conn: [orig_h=2620:0:e00:400e:d1d:db37:beb:5aac, resp_h=2001:4860:8006::63, itype=128, icode=0, len=32, v6=T]
|
||||||
|
icmp_redirect (tgt=fe80::cafe, dest=fe80::babe)
|
||||||
|
conn_id: [orig_h=fe80::dead, orig_p=137/icmp, resp_h=fe80::beef, resp_p=0/icmp]
|
||||||
|
icmp_conn: [orig_h=fe80::dead, resp_h=fe80::beef, itype=137, icode=0, len=32, v6=T]
|
||||||
|
icmp_router_advertisement (hop_limit=0, managed=F, rlifetime=1800, reachable=0.000000, retrans=0.000000)
|
||||||
|
conn_id: [orig_h=fe80::dead, orig_p=134/icmp, resp_h=fe80::beef, resp_p=133/icmp]
|
||||||
|
icmp_conn: [orig_h=fe80::dead, resp_h=fe80::beef, itype=134, icode=0, len=8, v6=T]
|
||||||
|
icmp_neighbor_advertisement (tgt=fe80::babe)
|
||||||
|
conn_id: [orig_h=fe80::dead, orig_p=136/icmp, resp_h=fe80::beef, resp_p=135/icmp]
|
||||||
|
icmp_conn: [orig_h=fe80::dead, resp_h=fe80::beef, itype=136, icode=0, len=16, v6=T]
|
||||||
|
icmp_router_solicitation
|
||||||
|
conn_id: [orig_h=fe80::dead, orig_p=133/icmp, resp_h=fe80::beef, resp_p=134/icmp]
|
||||||
|
icmp_conn: [orig_h=fe80::dead, resp_h=fe80::beef, itype=133, icode=0, len=0, v6=T]
|
||||||
|
icmp_neighbor_solicitation (tgt=fe80::babe)
|
||||||
|
conn_id: [orig_h=fe80::dead, orig_p=135/icmp, resp_h=fe80::beef, resp_p=136/icmp]
|
||||||
|
icmp_conn: [orig_h=fe80::dead, resp_h=fe80::beef, itype=135, icode=0, len=16, v6=T]
|
3
testing/btest/Baseline/core.truncation/output
Normal file
3
testing/btest/Baseline/core.truncation/output
Normal file
|
@ -0,0 +1,3 @@
|
||||||
|
1334160095.895421 weird: truncated_IP
|
||||||
|
1334156241.519125 weird: truncated_IP
|
||||||
|
1334094648.590126 weird: truncated_IP
|
BIN
testing/btest/Traces/chksums/ip4-icmp-bad-chksum.pcap
Normal file
BIN
testing/btest/Traces/chksums/ip4-icmp-bad-chksum.pcap
Normal file
Binary file not shown.
BIN
testing/btest/Traces/chksums/ip4-icmp-good-chksum.pcap
Normal file
BIN
testing/btest/Traces/chksums/ip4-icmp-good-chksum.pcap
Normal file
Binary file not shown.
BIN
testing/btest/Traces/chksums/ip6-icmp6-bad-chksum.pcap
Normal file
BIN
testing/btest/Traces/chksums/ip6-icmp6-bad-chksum.pcap
Normal file
Binary file not shown.
BIN
testing/btest/Traces/chksums/ip6-icmp6-good-chksum.pcap
Normal file
BIN
testing/btest/Traces/chksums/ip6-icmp6-good-chksum.pcap
Normal file
Binary file not shown.
BIN
testing/btest/Traces/chksums/ip6-route0-icmp6-bad-chksum.pcap
Normal file
BIN
testing/btest/Traces/chksums/ip6-route0-icmp6-bad-chksum.pcap
Normal file
Binary file not shown.
BIN
testing/btest/Traces/chksums/ip6-route0-icmp6-good-chksum.pcap
Normal file
BIN
testing/btest/Traces/chksums/ip6-route0-icmp6-good-chksum.pcap
Normal file
Binary file not shown.
BIN
testing/btest/Traces/icmp/icmp-destunreach-ip.pcap
Normal file
BIN
testing/btest/Traces/icmp/icmp-destunreach-ip.pcap
Normal file
Binary file not shown.
BIN
testing/btest/Traces/icmp/icmp-destunreach-no-context.pcap
Normal file
BIN
testing/btest/Traces/icmp/icmp-destunreach-no-context.pcap
Normal file
Binary file not shown.
BIN
testing/btest/Traces/icmp/icmp-ping.pcap
Normal file
BIN
testing/btest/Traces/icmp/icmp-ping.pcap
Normal file
Binary file not shown.
BIN
testing/btest/Traces/icmp/icmp-timeexceeded.pcap
Normal file
BIN
testing/btest/Traces/icmp/icmp-timeexceeded.pcap
Normal file
Binary file not shown.
BIN
testing/btest/Traces/icmp/icmp6-destunreach-ip6ext-trunc.pcap
Normal file
BIN
testing/btest/Traces/icmp/icmp6-destunreach-ip6ext-trunc.pcap
Normal file
Binary file not shown.
BIN
testing/btest/Traces/icmp/icmp6-destunreach-ip6ext-udp.pcap
Normal file
BIN
testing/btest/Traces/icmp/icmp6-destunreach-ip6ext-udp.pcap
Normal file
Binary file not shown.
BIN
testing/btest/Traces/icmp/icmp6-destunreach-ip6ext.pcap
Normal file
BIN
testing/btest/Traces/icmp/icmp6-destunreach-ip6ext.pcap
Normal file
Binary file not shown.
BIN
testing/btest/Traces/icmp/icmp6-destunreach-no-context.pcap
Normal file
BIN
testing/btest/Traces/icmp/icmp6-destunreach-no-context.pcap
Normal file
Binary file not shown.
BIN
testing/btest/Traces/icmp/icmp6-neighbor-advert.pcap
Normal file
BIN
testing/btest/Traces/icmp/icmp6-neighbor-advert.pcap
Normal file
Binary file not shown.
BIN
testing/btest/Traces/icmp/icmp6-neighbor-solicit.pcap
Normal file
BIN
testing/btest/Traces/icmp/icmp6-neighbor-solicit.pcap
Normal file
Binary file not shown.
BIN
testing/btest/Traces/icmp/icmp6-paramprob.pcap
Normal file
BIN
testing/btest/Traces/icmp/icmp6-paramprob.pcap
Normal file
Binary file not shown.
BIN
testing/btest/Traces/icmp/icmp6-ping.pcap
Normal file
BIN
testing/btest/Traces/icmp/icmp6-ping.pcap
Normal file
Binary file not shown.
BIN
testing/btest/Traces/icmp/icmp6-redirect.pcap
Normal file
BIN
testing/btest/Traces/icmp/icmp6-redirect.pcap
Normal file
Binary file not shown.
BIN
testing/btest/Traces/icmp/icmp6-router-advert.pcap
Normal file
BIN
testing/btest/Traces/icmp/icmp6-router-advert.pcap
Normal file
Binary file not shown.
BIN
testing/btest/Traces/icmp/icmp6-router-solicit.pcap
Normal file
BIN
testing/btest/Traces/icmp/icmp6-router-solicit.pcap
Normal file
Binary file not shown.
BIN
testing/btest/Traces/icmp/icmp6-timeexceeded.pcap
Normal file
BIN
testing/btest/Traces/icmp/icmp6-timeexceeded.pcap
Normal file
Binary file not shown.
BIN
testing/btest/Traces/icmp/icmp6-toobig.pcap
Normal file
BIN
testing/btest/Traces/icmp/icmp6-toobig.pcap
Normal file
Binary file not shown.
BIN
testing/btest/Traces/trunc/ip4-trunc.pcap
Normal file
BIN
testing/btest/Traces/trunc/ip4-trunc.pcap
Normal file
Binary file not shown.
BIN
testing/btest/Traces/trunc/ip6-ext-trunc.pcap
Normal file
BIN
testing/btest/Traces/trunc/ip6-ext-trunc.pcap
Normal file
Binary file not shown.
BIN
testing/btest/Traces/trunc/ip6-trunc.pcap
Normal file
BIN
testing/btest/Traces/trunc/ip6-trunc.pcap
Normal file
Binary file not shown.
|
@ -1,15 +1,23 @@
|
||||||
# @TEST-EXEC: bro -b -r $TRACES/chksums/ip4-bad-chksum.pcap >>bad.out 2>&1
|
# @TEST-EXEC: bro -b -r $TRACES/chksums/ip4-bad-chksum.pcap >>bad.out 2>&1
|
||||||
# @TEST-EXEC: bro -b -r $TRACES/chksums/ip4-tcp-bad-chksum.pcap >>bad.out 2>&1
|
# @TEST-EXEC: bro -b -r $TRACES/chksums/ip4-tcp-bad-chksum.pcap >>bad.out 2>&1
|
||||||
# @TEST-EXEC: bro -b -r $TRACES/chksums/ip4-udp-bad-chksum.pcap >>bad.out 2>&1
|
# @TEST-EXEC: bro -b -r $TRACES/chksums/ip4-udp-bad-chksum.pcap >>bad.out 2>&1
|
||||||
|
# @TEST-EXEC: bro -b -r $TRACES/chksums/ip4-icmp-bad-chksum.pcap >>bad.out 2>&1
|
||||||
# @TEST-EXEC: bro -b -r $TRACES/chksums/ip6-route0-tcp-bad-chksum.pcap >>bad.out 2>&1
|
# @TEST-EXEC: bro -b -r $TRACES/chksums/ip6-route0-tcp-bad-chksum.pcap >>bad.out 2>&1
|
||||||
# @TEST-EXEC: bro -b -r $TRACES/chksums/ip6-route0-udp-bad-chksum.pcap >>bad.out 2>&1
|
# @TEST-EXEC: bro -b -r $TRACES/chksums/ip6-route0-udp-bad-chksum.pcap >>bad.out 2>&1
|
||||||
|
# @TEST-EXEC: bro -b -r $TRACES/chksums/ip6-route0-icmp6-bad-chksum.pcap >>bad.out 2>&1
|
||||||
# @TEST-EXEC: bro -b -r $TRACES/chksums/ip6-tcp-bad-chksum.pcap >>bad.out 2>&1
|
# @TEST-EXEC: bro -b -r $TRACES/chksums/ip6-tcp-bad-chksum.pcap >>bad.out 2>&1
|
||||||
# @TEST-EXEC: bro -b -r $TRACES/chksums/ip6-udp-bad-chksum.pcap >>bad.out 2>&1
|
# @TEST-EXEC: bro -b -r $TRACES/chksums/ip6-udp-bad-chksum.pcap >>bad.out 2>&1
|
||||||
|
# @TEST-EXEC: bro -b -r $TRACES/chksums/ip6-icmp6-bad-chksum.pcap >>bad.out 2>&1
|
||||||
|
|
||||||
|
|
||||||
# @TEST-EXEC: bro -b -r $TRACES/chksums/ip4-tcp-good-chksum.pcap >>good.out 2>&1
|
# @TEST-EXEC: bro -b -r $TRACES/chksums/ip4-tcp-good-chksum.pcap >>good.out 2>&1
|
||||||
# @TEST-EXEC: bro -b -r $TRACES/chksums/ip4-udp-good-chksum.pcap >>good.out 2>&1
|
# @TEST-EXEC: bro -b -r $TRACES/chksums/ip4-udp-good-chksum.pcap >>good.out 2>&1
|
||||||
|
# @TEST-EXEC: bro -b -r $TRACES/chksums/ip4-icmp-good-chksum.pcap >>good.out 2>&1
|
||||||
# @TEST-EXEC: bro -b -r $TRACES/chksums/ip6-route0-tcp-good-chksum.pcap >>good.out 2>&1
|
# @TEST-EXEC: bro -b -r $TRACES/chksums/ip6-route0-tcp-good-chksum.pcap >>good.out 2>&1
|
||||||
# @TEST-EXEC: bro -b -r $TRACES/chksums/ip6-route0-udp-good-chksum.pcap >>good.out 2>&1
|
# @TEST-EXEC: bro -b -r $TRACES/chksums/ip6-route0-udp-good-chksum.pcap >>good.out 2>&1
|
||||||
|
# @TEST-EXEC: bro -b -r $TRACES/chksums/ip6-route0-icmp6-good-chksum.pcap >>good.out 2>&1
|
||||||
# @TEST-EXEC: bro -b -r $TRACES/chksums/ip6-tcp-good-chksum.pcap >>good.out 2>&1
|
# @TEST-EXEC: bro -b -r $TRACES/chksums/ip6-tcp-good-chksum.pcap >>good.out 2>&1
|
||||||
# @TEST-EXEC: bro -b -r $TRACES/chksums/ip6-udp-good-chksum.pcap >>good.out 2>&1
|
# @TEST-EXEC: bro -b -r $TRACES/chksums/ip6-udp-good-chksum.pcap >>good.out 2>&1
|
||||||
|
# @TEST-EXEC: bro -b -r $TRACES/chksums/ip6-icmp6-good-chksum.pcap >>good.out 2>&1
|
||||||
# @TEST-EXEC: btest-diff bad.out
|
# @TEST-EXEC: btest-diff bad.out
|
||||||
# @TEST-EXEC: btest-diff good.out
|
# @TEST-EXEC: btest-diff good.out
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
# @TEST-EXEC: bro -C -r $TRACES/wikipedia.trace discarder-ip.bro >output
|
# @TEST-EXEC: bro -C -r $TRACES/wikipedia.trace discarder-ip.bro >output
|
||||||
# @TEST-EXEC: bro -C -r $TRACES/wikipedia.trace discarder-tcp.bro >>output
|
# @TEST-EXEC: bro -C -r $TRACES/wikipedia.trace discarder-tcp.bro >>output
|
||||||
# @TEST-EXEC: bro -C -r $TRACES/wikipedia.trace discarder-udp.bro >>output
|
# @TEST-EXEC: bro -C -r $TRACES/wikipedia.trace discarder-udp.bro >>output
|
||||||
# @TEST-EXEC: bro -C -r $TRACES/icmp-unreach.trace discarder-icmp.bro >>output
|
# @TEST-EXEC: bro -C -r $TRACES/icmp/icmp-destunreach-udp.pcap discarder-icmp.bro >>output
|
||||||
# @TEST-EXEC: btest-diff output
|
# @TEST-EXEC: btest-diff output
|
||||||
|
|
||||||
@TEST-START-FILE discarder-ip.bro
|
@TEST-START-FILE discarder-ip.bro
|
||||||
|
|
14
testing/btest/core/icmp/icmp-context.test
Normal file
14
testing/btest/core/icmp/icmp-context.test
Normal file
|
@ -0,0 +1,14 @@
|
||||||
|
# These tests all check that IPv6 context packet construction for ICMP6 works.
|
||||||
|
|
||||||
|
# @TEST-EXEC: bro -b -r $TRACES/icmp/icmp-destunreach-no-context.pcap %INPUT >>output 2>&1
|
||||||
|
# @TEST-EXEC: bro -b -r $TRACES/icmp/icmp-destunreach-ip.pcap %INPUT >>output 2>&1
|
||||||
|
# @TEST-EXEC: bro -b -r $TRACES/icmp/icmp-destunreach-udp.pcap %INPUT >>output 2>&1
|
||||||
|
# @TEST-EXEC: btest-diff output
|
||||||
|
|
||||||
|
event icmp_unreachable(c: connection, icmp: icmp_conn, code: count, context: icmp_context)
|
||||||
|
{
|
||||||
|
print "icmp_unreachable (code=" + fmt("%d", code) + ")";
|
||||||
|
print " conn_id: " + fmt("%s", c$id);
|
||||||
|
print " icmp_conn: " + fmt("%s", icmp);
|
||||||
|
print " icmp_context: " + fmt("%s", context);
|
||||||
|
}
|
44
testing/btest/core/icmp/icmp-events.test
Normal file
44
testing/btest/core/icmp/icmp-events.test
Normal file
|
@ -0,0 +1,44 @@
|
||||||
|
# These tests all check that ICMP6 events get raised with correct arguments.
|
||||||
|
|
||||||
|
# @TEST-EXEC: bro -b -r $TRACES/icmp/icmp-destunreach-udp.pcap %INPUT >>output 2>&1
|
||||||
|
# @TEST-EXEC: bro -b -r $TRACES/icmp/icmp-timeexceeded.pcap %INPUT >>output 2>&1
|
||||||
|
# @TEST-EXEC: bro -b -r $TRACES/icmp/icmp-ping.pcap %INPUT >>output 2>&1
|
||||||
|
|
||||||
|
# @TEST-EXEC: btest-diff output
|
||||||
|
|
||||||
|
event icmp_sent(c: connection, icmp: icmp_conn)
|
||||||
|
{
|
||||||
|
print "icmp_sent";
|
||||||
|
print " conn_id: " + fmt("%s", c$id);
|
||||||
|
print " icmp_conn: " + fmt("%s", icmp);
|
||||||
|
}
|
||||||
|
|
||||||
|
event icmp_echo_request(c: connection, icmp: icmp_conn, id: count, seq: count, payload: string)
|
||||||
|
{
|
||||||
|
print "icmp_echo_request (id=" + fmt("%d", id) + ", seq=" + fmt("%d", seq) + ", payload=" + payload + ")";
|
||||||
|
print " conn_id: " + fmt("%s", c$id);
|
||||||
|
print " icmp_conn: " + fmt("%s", icmp);
|
||||||
|
}
|
||||||
|
|
||||||
|
event icmp_echo_reply(c: connection, icmp: icmp_conn, id: count, seq: count, payload: string)
|
||||||
|
{
|
||||||
|
print "icmp_echo_reply (id=" + fmt("%d", id) + ", seq=" + fmt("%d", seq) + ", payload=" + payload + ")";
|
||||||
|
print " conn_id: " + fmt("%s", c$id);
|
||||||
|
print " icmp_conn: " + fmt("%s", icmp);
|
||||||
|
}
|
||||||
|
|
||||||
|
event icmp_unreachable(c: connection, icmp: icmp_conn, code: count, context: icmp_context)
|
||||||
|
{
|
||||||
|
print "icmp_unreachable (code=" + fmt("%d", code) + ")";
|
||||||
|
print " conn_id: " + fmt("%s", c$id);
|
||||||
|
print " icmp_conn: " + fmt("%s", icmp);
|
||||||
|
print " icmp_context: " + fmt("%s", context);
|
||||||
|
}
|
||||||
|
|
||||||
|
event icmp_time_exceeded(c: connection, icmp: icmp_conn, code: count, context: icmp_context)
|
||||||
|
{
|
||||||
|
print "icmp_time_exceeded (code=" + fmt("%d", code) + ")";
|
||||||
|
print " conn_id: " + fmt("%s", c$id);
|
||||||
|
print " icmp_conn: " + fmt("%s", icmp);
|
||||||
|
print " icmp_context: " + fmt("%s", context);
|
||||||
|
}
|
15
testing/btest/core/icmp/icmp6-context.test
Normal file
15
testing/btest/core/icmp/icmp6-context.test
Normal file
|
@ -0,0 +1,15 @@
|
||||||
|
# These tests all check that IPv6 context packet construction for ICMP6 works.
|
||||||
|
|
||||||
|
# @TEST-EXEC: bro -b -r $TRACES/icmp/icmp6-destunreach-no-context.pcap %INPUT >>output 2>&1
|
||||||
|
# @TEST-EXEC: bro -b -r $TRACES/icmp/icmp6-destunreach-ip6ext-trunc.pcap %INPUT >>output 2>&1
|
||||||
|
# @TEST-EXEC: bro -b -r $TRACES/icmp/icmp6-destunreach-ip6ext-udp.pcap %INPUT >>output 2>&1
|
||||||
|
# @TEST-EXEC: bro -b -r $TRACES/icmp/icmp6-destunreach-ip6ext.pcap %INPUT >>output 2>&1
|
||||||
|
# @TEST-EXEC: btest-diff output
|
||||||
|
|
||||||
|
event icmp_unreachable(c: connection, icmp: icmp_conn, code: count, context: icmp_context)
|
||||||
|
{
|
||||||
|
print "icmp_unreachable (code=" + fmt("%d", code) + ")";
|
||||||
|
print " conn_id: " + fmt("%s", c$id);
|
||||||
|
print " icmp_conn: " + fmt("%s", icmp);
|
||||||
|
print " icmp_context: " + fmt("%s", context);
|
||||||
|
}
|
110
testing/btest/core/icmp/icmp6-events.test
Normal file
110
testing/btest/core/icmp/icmp6-events.test
Normal file
|
@ -0,0 +1,110 @@
|
||||||
|
# These tests all check that ICMP6 events get raised with correct arguments.
|
||||||
|
|
||||||
|
# @TEST-EXEC: bro -b -r $TRACES/icmp/icmp6-destunreach-ip6ext-udp.pcap %INPUT >>output 2>&1
|
||||||
|
# @TEST-EXEC: bro -b -r $TRACES/icmp/icmp6-toobig.pcap %INPUT >>output 2>&1
|
||||||
|
# @TEST-EXEC: bro -b -r $TRACES/icmp/icmp6-timeexceeded.pcap %INPUT >>output 2>&1
|
||||||
|
# @TEST-EXEC: bro -b -r $TRACES/icmp/icmp6-paramprob.pcap %INPUT >>output 2>&1
|
||||||
|
# @TEST-EXEC: bro -b -r $TRACES/icmp/icmp6-ping.pcap %INPUT >>output 2>&1
|
||||||
|
# @TEST-EXEC: bro -b -r $TRACES/icmp/icmp6-redirect.pcap %INPUT >>output 2>&1
|
||||||
|
# @TEST-EXEC: bro -b -r $TRACES/icmp/icmp6-router-advert.pcap %INPUT >>output 2>&1
|
||||||
|
# @TEST-EXEC: bro -b -r $TRACES/icmp/icmp6-neighbor-advert.pcap %INPUT >>output 2>&1
|
||||||
|
# @TEST-EXEC: bro -b -r $TRACES/icmp/icmp6-router-solicit.pcap %INPUT >>output 2>&1
|
||||||
|
# @TEST-EXEC: bro -b -r $TRACES/icmp/icmp6-neighbor-solicit.pcap %INPUT >>output 2>&1
|
||||||
|
|
||||||
|
# @TEST-EXEC: btest-diff output
|
||||||
|
|
||||||
|
event icmp_sent(c: connection, icmp: icmp_conn)
|
||||||
|
{
|
||||||
|
print "icmp_sent";
|
||||||
|
print " conn_id: " + fmt("%s", c$id);
|
||||||
|
print " icmp_conn: " + fmt("%s", icmp);
|
||||||
|
}
|
||||||
|
|
||||||
|
event icmp_echo_request(c: connection, icmp: icmp_conn, id: count, seq: count, payload: string)
|
||||||
|
{
|
||||||
|
print "icmp_echo_request (id=" + fmt("%d", id) + ", seq=" + fmt("%d", seq) + ", payload=" + payload + ")";
|
||||||
|
print " conn_id: " + fmt("%s", c$id);
|
||||||
|
print " icmp_conn: " + fmt("%s", icmp);
|
||||||
|
}
|
||||||
|
|
||||||
|
event icmp_echo_reply(c: connection, icmp: icmp_conn, id: count, seq: count, payload: string)
|
||||||
|
{
|
||||||
|
print "icmp_echo_reply (id=" + fmt("%d", id) + ", seq=" + fmt("%d", seq) + ", payload=" + payload + ")";
|
||||||
|
print " conn_id: " + fmt("%s", c$id);
|
||||||
|
print " icmp_conn: " + fmt("%s", icmp);
|
||||||
|
}
|
||||||
|
|
||||||
|
event icmp_unreachable(c: connection, icmp: icmp_conn, code: count, context: icmp_context)
|
||||||
|
{
|
||||||
|
print "icmp_unreachable (code=" + fmt("%d", code) + ")";
|
||||||
|
print " conn_id: " + fmt("%s", c$id);
|
||||||
|
print " icmp_conn: " + fmt("%s", icmp);
|
||||||
|
print " icmp_context: " + fmt("%s", context);
|
||||||
|
}
|
||||||
|
|
||||||
|
event icmp_packet_too_big(c: connection, icmp: icmp_conn, code: count, context: icmp_context)
|
||||||
|
{
|
||||||
|
print "icmp_packet_too_big (code=" + fmt("%d", code) + ")";
|
||||||
|
print " conn_id: " + fmt("%s", c$id);
|
||||||
|
print " icmp_conn: " + fmt("%s", icmp);
|
||||||
|
print " icmp_context: " + fmt("%s", context);
|
||||||
|
}
|
||||||
|
|
||||||
|
event icmp_time_exceeded(c: connection, icmp: icmp_conn, code: count, context: icmp_context)
|
||||||
|
{
|
||||||
|
print "icmp_time_exceeded (code=" + fmt("%d", code) + ")";
|
||||||
|
print " conn_id: " + fmt("%s", c$id);
|
||||||
|
print " icmp_conn: " + fmt("%s", icmp);
|
||||||
|
print " icmp_context: " + fmt("%s", context);
|
||||||
|
}
|
||||||
|
|
||||||
|
event icmp_parameter_problem(c: connection, icmp: icmp_conn, code: count, context: icmp_context)
|
||||||
|
{
|
||||||
|
print "icmp_parameter_problem (code=" + fmt("%d", code) + ")";
|
||||||
|
print " conn_id: " + fmt("%s", c$id);
|
||||||
|
print " icmp_conn: " + fmt("%s", icmp);
|
||||||
|
print " icmp_context: " + fmt("%s", context);
|
||||||
|
}
|
||||||
|
|
||||||
|
event icmp_redirect(c: connection, icmp: icmp_conn, tgt: addr, dest: addr)
|
||||||
|
{
|
||||||
|
print "icmp_redirect (tgt=" + fmt("%s", tgt) + ", dest=" + fmt("%s", dest) + ")";
|
||||||
|
print " conn_id: " + fmt("%s", c$id);
|
||||||
|
print " icmp_conn: " + fmt("%s", icmp);
|
||||||
|
}
|
||||||
|
|
||||||
|
event icmp_error_message(c: connection, icmp: icmp_conn, code: count, context: icmp_context)
|
||||||
|
{
|
||||||
|
print "icmp_error_message (code=" + fmt("%d", code) + ")";
|
||||||
|
print " conn_id: " + fmt("%s", c$id);
|
||||||
|
print " icmp_conn: " + fmt("%s", icmp);
|
||||||
|
print " icmp_context: " + fmt("%s", context);
|
||||||
|
}
|
||||||
|
|
||||||
|
event icmp_neighbor_solicitation(c: connection, icmp: icmp_conn, tgt: addr)
|
||||||
|
{
|
||||||
|
print "icmp_neighbor_solicitation (tgt=" + fmt("%s", tgt) + ")";
|
||||||
|
print " conn_id: " + fmt("%s", c$id);
|
||||||
|
print " icmp_conn: " + fmt("%s", icmp);
|
||||||
|
}
|
||||||
|
|
||||||
|
event icmp_neighbor_advertisement(c: connection, icmp: icmp_conn, tgt:addr)
|
||||||
|
{
|
||||||
|
print "icmp_neighbor_advertisement (tgt=" + fmt("%s", tgt) + ")";
|
||||||
|
print " conn_id: " + fmt("%s", c$id);
|
||||||
|
print " icmp_conn: " + fmt("%s", icmp);
|
||||||
|
}
|
||||||
|
|
||||||
|
event icmp_router_solicitation(c: connection, icmp: icmp_conn)
|
||||||
|
{
|
||||||
|
print "icmp_router_solicitation";
|
||||||
|
print " conn_id: " + fmt("%s", c$id);
|
||||||
|
print " icmp_conn: " + fmt("%s", icmp);
|
||||||
|
}
|
||||||
|
|
||||||
|
event icmp_router_advertisement(c: connection, icmp: icmp_conn, hop_limit: count, managed: bool, router_lifetime: count, reachable_time: interval, retrans_timer: interval)
|
||||||
|
{
|
||||||
|
print "icmp_router_advertisement (hop_limit=" + fmt("%d", hop_limit) + ", managed=" + fmt("%s", managed) + ", rlifetime=" + fmt("%d", router_lifetime) + ", reachable=" + fmt("%f", reachable_time) + ", retrans=" + fmt("%f", retrans_timer) + ")";
|
||||||
|
print " conn_id: " + fmt("%s", c$id);
|
||||||
|
print " icmp_conn: " + fmt("%s", icmp);
|
||||||
|
}
|
|
@ -3,5 +3,6 @@
|
||||||
|
|
||||||
event new_connection(c: connection)
|
event new_connection(c: connection)
|
||||||
{
|
{
|
||||||
print c$id;
|
if ( c$id$resp_p == 80/tcp )
|
||||||
|
print c$id;
|
||||||
}
|
}
|
||||||
|
|
6
testing/btest/core/truncation.test
Normal file
6
testing/btest/core/truncation.test
Normal file
|
@ -0,0 +1,6 @@
|
||||||
|
# Truncated IP packet's should not be analyzed, and generate truncated_IP weird
|
||||||
|
|
||||||
|
# @TEST-EXEC: bro -b -r $TRACES/trunc/ip4-trunc.pcap >>output 2>&1
|
||||||
|
# @TEST-EXEC: bro -b -r $TRACES/trunc/ip6-trunc.pcap >>output 2>&1
|
||||||
|
# @TEST-EXEC: bro -b -r $TRACES/trunc/ip6-ext-trunc.pcap >>output 2>&1
|
||||||
|
# @TEST-EXEC: btest-diff output
|
Loading…
Add table
Add a link
Reference in a new issue