Merge remote-tracking branch 'origin/master' into topic/bernhard/input-threads

This commit is contained in:
Bernhard Amann 2012-04-18 09:28:49 -07:00
commit a2f1af12fa
77 changed files with 1333 additions and 379 deletions

51
CHANGES
View file

@ -1,4 +1,55 @@
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
* Small updates for the bittorrent analyzer to support 64bit types
in binpac. (Seth Hall)
* Removed the attempt at bittorrent resynchronization. (Seth Hall)
2.0-276 | 2012-04-17 17:35:56 -0700
* Add more support for <netinet/ip6.h>'s that lack some structure
definitions. (Jon Siwek)
2.0-273 | 2012-04-16 18:08:56 -0700
* Removing QR flag from DNS log in response, which should not have
been there in the first place. (Seth Hall)
* Sync up patricia.c/h with pysubnettree repo. (Daniel Thayer)
* Adding missing leak groups to a couple tests. Also activating leak
checking for proxy in basic-cluster test. (Robin Sommer)
2.0-267 | 2012-04-09 17:47:28 -0700 2.0-267 | 2012-04-09 17:47:28 -0700
* Add support for mobile IPv6 Mobility Header (RFC 6275). (Jon * Add support for mobile IPv6 Mobility Header (RFC 6275). (Jon

5
NEWS
View file

@ -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

View file

@ -1 +1 @@
2.0-267 2.0-301

@ -1 +1 @@
Subproject commit 56ae73ab995dda665d8918d1a6b3af39b15991e3 Subproject commit 71c37019bc371eb7863fb6aa47a7daa4540f4f1f

@ -1 +1 @@
Subproject commit 12d32194c19d2dce06818588a2aeccf234de1889 Subproject commit d885987e7968669e34504b0403ac89bd13928e9a

@ -1 +1 @@
Subproject commit 60898666ba1df1913c08ad5045b1e56f974060cc Subproject commit bead1168ae9c2d2ae216dd58522fbc05498ff2c8

@ -1 +1 @@
Subproject commit 2524b3aeda916b5daaad215c42860c1477c2606b Subproject commit 44cc3de5f6f98a86b2516bdc48dd168e6a6a28fd

@ -1 +1 @@
Subproject commit 8da6c55697ff580600cfff474f4ccba2a592f911 Subproject commit 1897d224ce295e91d20e458851759c99734a0a74

2
cmake

@ -1 +1 @@
Subproject commit 5ddec4556338339fc4d1da27bce766a827990543 Subproject commit 49278736c1404cb8c077272b80312c947e68bf52

View file

@ -152,3 +152,47 @@
#ifndef HAVE_DLT_PPP_SERIAL #ifndef HAVE_DLT_PPP_SERIAL
#define DLT_PPP_SERIAL @DLT_PPP_SERIAL@ #define DLT_PPP_SERIAL @DLT_PPP_SERIAL@
#endif #endif
/* IPv6 Next Header values defined by RFC 3542 */
#cmakedefine HAVE_IPPROTO_HOPOPTS
#ifndef HAVE_IPPROTO_HOPOPTS
#define IPPROTO_HOPOPTS 0
#endif
#cmakedefine HAVE_IPPROTO_IPV6
#ifndef HAVE_IPPROTO_IPV6
#define IPPROTO_IPV6 41
#endif
#cmakedefine HAVE_IPPROTO_ROUTING
#ifndef HAVE_IPPROTO_ROUTING
#define IPPROTO_ROUTING 43
#endif
#cmakedefine HAVE_IPPROTO_FRAGMENT
#ifndef HAVE_IPPROTO_FRAGMENT
#define IPPROTO_FRAGMENT 44
#endif
#cmakedefine HAVE_IPPROTO_ESP
#ifndef HAVE_IPPROTO_ESP
#define IPPROTO_ESP 50
#endif
#cmakedefine HAVE_IPPROTO_AH
#ifndef HAVE_IPPROTO_AH
#define IPPROTO_AH 51
#endif
#cmakedefine HAVE_IPPROTO_ICMPV6
#ifndef HAVE_IPPROTO_ICMPV6
#define IPPROTO_ICMPV6 58
#endif
#cmakedefine HAVE_IPPROTO_NONE
#ifndef HAVE_IPPROTO_NONE
#define IPPROTO_NONE 59
#endif
#cmakedefine HAVE_IPPROTO_DSTOPTS
#ifndef HAVE_IPPROTO_DSTOPTS
#define IPPROTO_DSTOPTS 60
#endif
/* IPv6 options structure defined by RFC 3542 */
#cmakedefine HAVE_IP6_OPT
/* Common IPv6 extension structure */
#cmakedefine HAVE_IP6_EXT

View file

@ -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.

View file

@ -39,8 +39,6 @@ export {
rcode: count &log &optional; rcode: count &log &optional;
## A descriptive name for the response code value. ## A descriptive name for the response code value.
rcode_name: string &log &optional; rcode_name: string &log &optional;
## Whether the message is a query (F) or response (T).
QR: bool &log &default=F;
## The Authoritative Answer bit for response messages specifies that ## The Authoritative Answer bit for response messages specifies that
## the responding name server is an authority for the domain name ## the responding name server is an authority for the domain name
## in the question section. ## in the question section.

View file

@ -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 },

View file

@ -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,

View file

@ -66,39 +66,44 @@ void BitTorrent_Analyzer::DeliverStream(int len, const u_char* data, bool orig)
void BitTorrent_Analyzer::Undelivered(int seq, int len, bool orig) void BitTorrent_Analyzer::Undelivered(int seq, int len, bool orig)
{ {
uint64 entry_offset = orig ?
*interp->upflow()->next_message_offset() :
*interp->downflow()->next_message_offset();
uint64& this_stream_len = orig ? stream_len_orig : stream_len_resp;
bool& this_stop = orig ? stop_orig : stop_resp;
TCP_ApplicationAnalyzer::Undelivered(seq, len, orig); TCP_ApplicationAnalyzer::Undelivered(seq, len, orig);
this_stream_len += len; // TODO: Code commented out for now. I think that shoving data that
// is definitely wrong into the parser seems like a really bad idea.
// The way it's currently tracking the next message offset isn't
// compatible with new 64bit int support in binpac either.
if ( entry_offset < this_stream_len ) //uint64 entry_offset = orig ?
{ // entry point is somewhere in the gap // *interp->upflow()->next_message_offset() :
DeliverWeird("Stopping BitTorrent analysis: cannot recover from content gap", orig); // *interp->downflow()->next_message_offset();
this_stop = true; //uint64& this_stream_len = orig ? stream_len_orig : stream_len_resp;
if ( stop_orig && stop_resp ) //bool& this_stop = orig ? stop_orig : stop_resp;
ProtocolViolation("BitTorrent: content gap and/or protocol violation"); //
} //this_stream_len += len;
else //
{ // fill the gap //if ( entry_offset < this_stream_len )
try // { // entry point is somewhere in the gap
{ // DeliverWeird("Stopping BitTorrent analysis: cannot recover from content gap", orig);
u_char gap[len]; // this_stop = true;
memset(gap, 0, len); // if ( stop_orig && stop_resp )
interp->NewData(orig, gap, gap + len); // ProtocolViolation("BitTorrent: content gap and/or protocol violation");
} // }
catch ( binpac::Exception const &e ) //else
{ // { // fill the gap
DeliverWeird("Stopping BitTorrent analysis: filling content gap failed", orig); // try
this_stop = true; // {
if ( stop_orig && stop_resp ) // u_char gap[len];
ProtocolViolation("BitTorrent: content gap and/or protocol violation"); // memset(gap, 0, len);
} // interp->NewData(orig, gap, gap + len);
} // }
// catch ( binpac::Exception const &e )
// {
// DeliverWeird("Stopping BitTorrent analysis: filling content gap failed", orig);
// this_stop = true;
// if ( stop_orig && stop_resp )
// ProtocolViolation("BitTorrent: content gap and/or protocol violation");
// }
// }
} }
void BitTorrent_Analyzer::EndpointEOF(TCP_Reassembler* endp) void BitTorrent_Analyzer::EndpointEOF(TCP_Reassembler* endp)

View file

@ -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;
switch ( icmpp->icmp_type ) {
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); root = icmp = new ICMP_Analyzer(conn);
DBG_DPD(conn, "activated ICMP analyzer");
analyzed = true; analyzed = true;
break; break;
} }

View file

@ -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

View file

@ -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,14 +48,34 @@ 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 )
{
int chksum = 0;
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"); Weird("bad_ICMP_checksum");
return; 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,55 +216,25 @@ 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();
uint32 ip_len, frag_offset;
TransportProto proto = TRANSPORT_UNKNOWN;
int DF, MF, bad_hdr_len, bad_checksum;
uint32 src_addr, dst_addr;
uint32 src_port, dst_port;
if ( ip_hdr_len < sizeof(struct ip) || ip_hdr_len > uint32(len) )
{ // We don't have an entire IP header.
bad_hdr_len = 1;
ip_len = frag_offset = 0;
DF = MF = bad_checksum = 0;
src_addr = dst_addr = 0;
src_port = dst_port = 0;
}
if ( ip4 )
transport_hdr = ((u_char *) ip_hdr->IP4_Hdr() + ip_hdr_len);
else else
{ transport_hdr = ((u_char *) ip_hdr->IP6_Hdr() + ip_hdr_len);
bad_hdr_len = 0;
ip_len = ntohs(ip->ip_len);
bad_checksum = ones_complement_checksum((void*) ip, ip_hdr_len, 0) != 0xffff;
src_addr = uint32(ip->ip_src.s_addr); TransportProto proto;
dst_addr = uint32(ip->ip_dst.s_addr);
switch ( ip->ip_p ) { switch ( ip_hdr->NextProto() ) {
case 1: proto = TRANSPORT_ICMP; break; case 1: proto = TRANSPORT_ICMP; break;
case 6: proto = TRANSPORT_TCP; break; case 6: proto = TRANSPORT_TCP; break;
case 17: proto = TRANSPORT_UDP; break; case 17: proto = TRANSPORT_UDP; break;
case 58: proto = TRANSPORT_ICMP; break;
// Default uses TRANSPORT_UNKNOWN, per initialization above. default: proto = TRANSPORT_UNKNOWN; break;
}
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
// port numbers are included in the ICMP.
bad_hdr_len = 1;
src_port = dst_port = 0;
} }
switch ( proto ) { switch ( proto ) {
@ -181,33 +243,87 @@ RecordVal* ICMP_Analyzer::ExtractICMPContext(int len, const u_char*& data)
const struct icmp* icmpp = const struct icmp* icmpp =
(const struct icmp *) transport_hdr; (const struct icmp *) transport_hdr;
bool is_one_way; // dummy bool is_one_way; // dummy
src_port = ntohs(icmpp->icmp_type); *src_port = ntohs(icmpp->icmp_type);
dst_port = ntohs(ICMP_counterpart(icmpp->icmp_type,
icmpp->icmp_code, if ( ip4 )
is_one_way)); *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; break;
}
case TRANSPORT_TCP: case TRANSPORT_TCP:
{ {
const struct tcphdr* tp = const struct tcphdr* tp =
(const struct tcphdr *) transport_hdr; (const struct tcphdr *) transport_hdr;
src_port = ntohs(tp->th_sport); *src_port = ntohs(tp->th_sport);
dst_port = ntohs(tp->th_dport); *dst_port = ntohs(tp->th_dport);
}
break; break;
}
case TRANSPORT_UDP: case TRANSPORT_UDP:
{ {
const struct udphdr* up = const struct udphdr* up =
(const struct udphdr *) transport_hdr; (const struct udphdr *) transport_hdr;
src_port = ntohs(up->uh_sport); *src_port = ntohs(up->uh_sport);
dst_port = ntohs(up->uh_dport); *dst_port = ntohs(up->uh_dport);
}
break; break;
}
default: default:
src_port = dst_port = ntohs(0); *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;
TransportProto proto = TRANSPORT_UNKNOWN;
int DF, MF, bad_hdr_len, bad_checksum;
IPAddr src_addr, dst_addr;
uint32 src_port, dst_port;
if ( len < (int)sizeof(struct ip) || ip_hdr_len > uint32(len) )
{
// We don't have an entire IP header.
bad_hdr_len = 1;
ip_len = frag_offset = 0;
DF = MF = bad_checksum = 0;
src_port = dst_port = 0;
}
else
{
bad_hdr_len = 0;
ip_len = ip_hdr->TotalLen();
bad_checksum = (ones_complement_checksum((void*) ip_hdr->IP4_Hdr(), ip_hdr_len, 0) != 0xffff);
src_addr = ip_hdr->SrcAddr();
dst_addr = ip_hdr->DstAddr();
DF = ip_hdr->DF();
MF = ip_hdr->MF();
frag_offset = ip_hdr->FragOffset();
if ( uint32(len) >= ip_hdr_len + 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;
} }
} }
@ -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;
}
}

View file

@ -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

View file

@ -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

View file

@ -12,7 +12,6 @@
#include <vector> #include <vector>
#include <netinet/in.h> #include <netinet/in.h>
#include <netinet/ip.h> #include <netinet/ip.h>
#include <netinet/ip6.h>
#ifdef ENABLE_MOBILE_IPV6 #ifdef ENABLE_MOBILE_IPV6
@ -142,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()
{ {
@ -250,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
@ -294,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 )
@ -304,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
{ {
@ -314,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 )
@ -340,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; }
/** /**
@ -441,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(); }

View file

@ -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;

View file

@ -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;

View file

@ -10,25 +10,25 @@ flow BitTorrent_Flow(is_orig: bool) {
%member{ %member{
bool handshake_ok; bool handshake_ok;
uint64 _next_message_offset; //uint64 _next_message_offset;
%} %}
%init{ %init{
handshake_ok = false; handshake_ok = false;
_next_message_offset = 0; //_next_message_offset = 0;
%} %}
function next_message_offset(): uint64 #function next_message_offset(): uint64
%{ # %{
return &_next_message_offset; # return &_next_message_offset;
%} # %}
function increment_next_message_offset(go: bool, len: uint32): bool #function increment_next_message_offset(go: bool, len: uint32): bool
%{ # %{
if ( go ) # if ( go )
_next_message_offset += len; # _next_message_offset += len;
return true; # return true;
%} # %}
function is_handshake_delivered(): bool function is_handshake_delivered(): bool
%{ %{

View file

@ -22,8 +22,8 @@ type BitTorrent_Handshake = record {
} &length = 68, &let { } &length = 68, &let {
validate: bool = $context.flow.validate_handshake(pstrlen, pstr); validate: bool = $context.flow.validate_handshake(pstrlen, pstr);
incoffsetffset: bool = #incoffsetffset: bool =
$context.flow.increment_next_message_offset(true, 68); # $context.flow.increment_next_message_offset(true, 68);
deliver: bool = deliver: bool =
$context.flow.deliver_handshake(reserved, info_hash, peer_id); $context.flow.deliver_handshake(reserved, info_hash, peer_id);
}; };
@ -72,8 +72,8 @@ type BitTorrent_PieceHeader(len: uint32) = record {
index: uint32; index: uint32;
begin: uint32; begin: uint32;
} &let { } &let {
incoffset: bool = #incoffset: bool =
$context.flow.increment_next_message_offset(true, len + 5); # $context.flow.increment_next_message_offset(true, len + 5);
}; };
type BitTorrent_Piece(len: uint32) = record { type BitTorrent_Piece(len: uint32) = record {
@ -134,9 +134,9 @@ type BitTorrent_Message = record {
default -> message_id: BitTorrent_MessageID(len.len); default -> message_id: BitTorrent_MessageID(len.len);
}; };
} &length = 4 + len.len, &let { } &length = 4 + len.len, &let {
incoffset: bool = $context.flow.increment_next_message_offset( #incoffset: bool = $context.flow.increment_next_message_offset(
len.len == 0 || message_id.id != TYPE_PIECE, # len.len == 0 || message_id.id != TYPE_PIECE,
4 + len.len); # 4 + len.len);
}; };
type BitTorrent_PDU = case $context.flow.is_handshake_delivered() of { type BitTorrent_PDU = case $context.flow.is_handshake_delivered() of {

View file

@ -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

View file

@ -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

View file

@ -31,13 +31,82 @@ typedef enum { IPv4, IPv6 } IPFamily;
#ifdef HAVE_NETINET_IP6_H #ifdef HAVE_NETINET_IP6_H
#include <netinet/ip6.h> #include <netinet/ip6.h>
#else
struct ip6_hdr { #ifndef HAVE_IP6_OPT
uint16 ip6_plen; struct ip6_opt {
uint8 ip6_nxt; uint8 ip6o_type;
uint8 ip6_hlim; uint8 ip6o_len;
}; };
#endif #endif // HAVE_IP6_OPT
#ifndef HAVE_IP6_EXT
struct ip6_ext {
uint8 ip6e_nxt;
uint8 ip6e_len;
};
#endif // HAVE_IP6_EXT
#else
struct ip6_hdr {
union {
struct ip6_hdrctl {
uint32 ip6_un1_flow; /* 4 bits version, 8 bits TC, 20 bits
flow-ID */
uint16 ip6_un1_plen; /* payload length */
uint8 ip6_un1_nxt; /* next header */
uint8 ip6_un1_hlim; /* hop limit */
} ip6_un1;
uint8 ip6_un2_vfc; /* 4 bits version, top 4 bits tclass */
} ip6_ctlun;
struct in6_addr ip6_src; /* source address */
struct in6_addr ip6_dst; /* destination address */
};
#define ip6_vfc ip6_ctlun.ip6_un2_vfc
#define ip6_flow ip6_ctlun.ip6_un1.ip6_un1_flow
#define ip6_plen ip6_ctlun.ip6_un1.ip6_un1_plen
#define ip6_nxt ip6_ctlun.ip6_un1.ip6_un1_nxt
#define ip6_hlim ip6_ctlun.ip6_un1.ip6_un1_hlim
#define ip6_hops ip6_ctlun.ip6_un1.ip6_un1_hlim
struct ip6_opt {
uint8 ip6o_type;
uint8 ip6o_len;
};
struct ip6_ext {
uint8 ip6e_nxt;
uint8 ip6e_len;
};
struct ip6_frag {
uint8 ip6f_nxt; /* next header */
uint8 ip6f_reserved; /* reserved field */
uint16 ip6f_offlg; /* offset, reserved, and flag */
uint32 ip6f_ident; /* identification */
};
struct ip6_hbh {
uint8 ip6h_nxt; /* next header */
uint8 ip6h_len; /* length in units of 8 octets */
/* followed by options */
};
struct ip6_dest {
uint8 ip6d_nxt; /* next header */
uint8 ip6d_len; /* length in units of 8 octets */
/* followed by options */
};
struct ip6_rthdr {
uint8 ip6r_nxt; /* next header */
uint8 ip6r_len; /* length in units of 8 octets */
uint8 ip6r_type; /* routing type */
uint8 ip6r_segleft; /* segments left */
/* followed by routing type specific data */
};
#endif // HAVE_NETINET_IP6_H
// For Solaris. // For Solaris.
#if !defined(TCPOPT_WINDOW) && defined(TCPOPT_WSCALE) #if !defined(TCPOPT_WINDOW) && defined(TCPOPT_WSCALE)
@ -65,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

View file

@ -115,16 +115,12 @@ local_inet_pton (int af, const char *src, void *dst)
} }
} }
#ifdef NT #ifdef NT
#ifdef HAVE_IPV6
else if (af == AF_INET6) { else if (af == AF_INET6) {
struct in6_addr Address; struct in6_addr Address;
return (inet6_addr(src, &Address)); return (inet6_addr(src, &Address));
} }
#endif /* HAVE_IPV6 */ #else
#endif /* NT */
#ifndef NT
else { else {
errno = EAFNOSUPPORT; errno = EAFNOSUPPORT;
return -1; return -1;
} }
@ -160,10 +156,8 @@ my_inet_pton (int af, const char *src, void *dst)
} }
memcpy (dst, xp, 4); memcpy (dst, xp, 4);
return (1); return (1);
#ifdef HAVE_IPV6
} else if (af == AF_INET6) { } else if (af == AF_INET6) {
return (local_inet_pton (af, src, dst)); return (local_inet_pton (af, src, dst));
#endif /* HAVE_IPV6 */
} else { } else {
#ifndef NT #ifndef NT
errno = EAFNOSUPPORT; errno = EAFNOSUPPORT;
@ -217,7 +211,6 @@ prefix_toa2x (prefix_t *prefix, char *buff, int with_len)
} }
return (buff); return (buff);
} }
#ifdef HAVE_IPV6
else if (prefix->family == AF_INET6) { else if (prefix->family == AF_INET6) {
char *r; char *r;
r = (char *) inet_ntop (AF_INET6, &prefix->add.sin6, buff, 48 /* a guess value */ ); r = (char *) inet_ntop (AF_INET6, &prefix->add.sin6, buff, 48 /* a guess value */ );
@ -227,7 +220,6 @@ prefix_toa2x (prefix_t *prefix, char *buff, int with_len)
} }
return (buff); return (buff);
} }
#endif /* HAVE_IPV6 */
else else
return (NULL); return (NULL);
} }
@ -255,7 +247,6 @@ New_Prefix2 (int family, void *dest, int bitlen, prefix_t *prefix)
int dynamic_allocated = 0; int dynamic_allocated = 0;
int default_bitlen = 32; int default_bitlen = 32;
#ifdef HAVE_IPV6
if (family == AF_INET6) { if (family == AF_INET6) {
default_bitlen = 128; default_bitlen = 128;
if (prefix == NULL) { if (prefix == NULL) {
@ -265,7 +256,6 @@ New_Prefix2 (int family, void *dest, int bitlen, prefix_t *prefix)
memcpy (&prefix->add.sin6, dest, 16); memcpy (&prefix->add.sin6, dest, 16);
} }
else else
#endif /* HAVE_IPV6 */
if (family == AF_INET) { if (family == AF_INET) {
if (prefix == NULL) { if (prefix == NULL) {
#ifndef NT #ifndef NT
@ -308,9 +298,7 @@ ascii2prefix (int family, char *string)
u_long bitlen, maxbitlen = 0; u_long bitlen, maxbitlen = 0;
char *cp; char *cp;
struct in_addr sin; struct in_addr sin;
#ifdef HAVE_IPV6
struct in6_addr sin6; struct in6_addr sin6;
#endif /* HAVE_IPV6 */
int result; int result;
char save[MAXLINE]; char save[MAXLINE];
@ -320,19 +308,15 @@ ascii2prefix (int family, char *string)
/* easy way to handle both families */ /* easy way to handle both families */
if (family == 0) { if (family == 0) {
family = AF_INET; family = AF_INET;
#ifdef HAVE_IPV6
if (strchr (string, ':')) family = AF_INET6; if (strchr (string, ':')) family = AF_INET6;
#endif /* HAVE_IPV6 */
} }
if (family == AF_INET) { if (family == AF_INET) {
maxbitlen = 32; maxbitlen = 32;
} }
#ifdef HAVE_IPV6
else if (family == AF_INET6) { else if (family == AF_INET6) {
maxbitlen = 128; maxbitlen = 128;
} }
#endif /* HAVE_IPV6 */
if ((cp = strchr (string, '/')) != NULL) { if ((cp = strchr (string, '/')) != NULL) {
bitlen = atol (cp + 1); bitlen = atol (cp + 1);
@ -355,7 +339,6 @@ ascii2prefix (int family, char *string)
return (New_Prefix (AF_INET, &sin, bitlen)); return (New_Prefix (AF_INET, &sin, bitlen));
} }
#ifdef HAVE_IPV6
else if (family == AF_INET6) { else if (family == AF_INET6) {
// Get rid of this with next IPv6 upgrade // Get rid of this with next IPv6 upgrade
#if defined(NT) && !defined(HAVE_INET_NTOP) #if defined(NT) && !defined(HAVE_INET_NTOP)
@ -367,7 +350,6 @@ ascii2prefix (int family, char *string)
#endif /* NT */ #endif /* NT */
return (New_Prefix (AF_INET6, &sin6, bitlen)); return (New_Prefix (AF_INET6, &sin6, bitlen));
} }
#endif /* HAVE_IPV6 */
else else
return (NULL); return (NULL);
} }

View file

@ -52,11 +52,6 @@
#include <sys/types.h> #include <sys/types.h>
#ifndef HAVE_IPV6
#define HAVE_IPV6
#endif
/* typedef unsigned int u_int; */ /* typedef unsigned int u_int; */
typedef void (*void_fn_t)(); typedef void (*void_fn_t)();
/* { from defs.h */ /* { from defs.h */
@ -86,9 +81,7 @@ typedef struct _prefix_t {
int ref_count; /* reference count */ int ref_count; /* reference count */
union { union {
struct in_addr sin; struct in_addr sin;
#ifdef HAVE_IPV6
struct in6_addr sin6; struct in6_addr sin6;
#endif /* IPV6 */
} add; } add;
} prefix_t; } prefix_t;

View file

@ -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

View file

@ -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

View 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]

View 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]

View 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]

View 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]

View file

@ -3,7 +3,7 @@
#empty_field (empty) #empty_field (empty)
#unset_field - #unset_field -
#path dns #path dns
#fields ts uid id.orig_h id.orig_p id.resp_h id.resp_p proto trans_id query qclass qclass_name qtype qtype_name rcode rcode_name QR AA TC RD RA Z answers TTLs #fields ts uid id.orig_h id.orig_p id.resp_h id.resp_p proto trans_id query qclass qclass_name qtype qtype_name rcode rcode_name AA TC RD RA Z answers TTLs
#types time string addr port addr port enum count string count string count string count string bool bool bool bool bool count vector[string] vector[interval] #types time string addr port addr port enum count string count string count string count string bool bool bool bool count vector[string] vector[interval]
1331084278.438444 UWkUyAuUGXf 2001:470:1f11:81f:d138:5f55:6d4:1fe2 51850 2607:f740:b::f93 53 udp 3903 txtpadding_323.n1.netalyzr.icsi.berkeley.edu 1 C_INTERNET 16 TXT 0 NOERROR F T F T F 0 This TXT record should be ignored 1.000000 1331084278.438444 UWkUyAuUGXf 2001:470:1f11:81f:d138:5f55:6d4:1fe2 51850 2607:f740:b::f93 53 udp 3903 txtpadding_323.n1.netalyzr.icsi.berkeley.edu 1 C_INTERNET 16 TXT 0 NOERROR T F T F 0 This TXT record should be ignored 1.000000
1331084293.592245 arKYeMETxOg 2001:470:1f11:81f:d138:5f55:6d4:1fe2 51851 2607:f740:b::f93 53 udp 40849 txtpadding_3230.n1.netalyzr.icsi.berkeley.edu 1 C_INTERNET 16 TXT 0 NOERROR F T F T F 0 This TXT record should be ignored 1.000000 1331084293.592245 arKYeMETxOg 2001:470:1f11:81f:d138:5f55:6d4:1fe2 51851 2607:f740:b::f93 53 udp 40849 txtpadding_3230.n1.netalyzr.icsi.berkeley.edu 1 C_INTERNET 16 TXT 0 NOERROR T F T F 0 This TXT record should be ignored 1.000000

View file

@ -0,0 +1,3 @@
1334160095.895421 weird: truncated_IP
1334156241.519125 weird: truncated_IP
1334094648.590126 weird: truncated_IP

View file

@ -3,6 +3,6 @@
#empty_field (empty) #empty_field (empty)
#unset_field - #unset_field -
#path dns #path dns
#fields ts uid id.orig_h id.orig_p id.resp_h id.resp_p proto trans_id query qclass qclass_name qtype qtype_name rcode rcode_name QR AA TC RD RA Z answers TTLs auth addl #fields ts uid id.orig_h id.orig_p id.resp_h id.resp_p proto trans_id query qclass qclass_name qtype qtype_name rcode rcode_name AA TC RD RA Z answers TTLs auth addl
#types time string addr port addr port enum count string count string count string count string bool bool bool bool bool count vector[string] vector[interval] table[string] table[string] #types time string addr port addr port enum count string count string count string count string bool bool bool bool count vector[string] vector[interval] table[string] table[string]
930613226.529070 UWkUyAuUGXf 212.180.42.100 25000 131.243.64.3 53 tcp 34798 - - - - - 0 NOERROR F F F F T 0 4.3.2.1 31337.000000 - - 930613226.529070 UWkUyAuUGXf 212.180.42.100 25000 131.243.64.3 53 tcp 34798 - - - - - 0 NOERROR F F F T 0 4.3.2.1 31337.000000 - -

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

View file

@ -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

View file

@ -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

View 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);
}

View 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);
}

View 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);
}

View 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);
}

View file

@ -3,5 +3,6 @@
event new_connection(c: connection) event new_connection(c: connection)
{ {
if ( c$id$resp_p == 80/tcp )
print c$id; print c$id;
} }

View file

@ -1,8 +1,11 @@
# Needs perftools support. # Needs perftools support.
# #
# @TEST-GROUP: leaks
# @TEST-REQUIRES: bro --help 2>&1 | grep -q mem-leaks # @TEST-REQUIRES: bro --help 2>&1 | grep -q mem-leaks
# @TEST-EXEC: btest-bg-run manager-1 HEAP_CHECK_DUMP_DIRECTORY=. HEAPCHECK=local BROPATH=$BROPATH:.. CLUSTER_NODE=manager-1 bro -m %INPUT # @TEST-EXEC: btest-bg-run manager-1 HEAP_CHECK_DUMP_DIRECTORY=. HEAPCHECK=local BROPATH=$BROPATH:.. CLUSTER_NODE=manager-1 bro -m %INPUT
# @TEST-EXEC: btest-bg-run proxy-1 BROPATH=$BROPATH:.. CLUSTER_NODE=proxy-1 bro %INPUT # @TEST-EXEC: btest-bg-run proxy-1 HEAP_CHECK_DUMP_DIRECTORY=. HEAPCHECK=local BROPATH=$BROPATH:.. CLUSTER_NODE=proxy-1 bro -m %INPUT
# @TEST-EXEC: sleep 1 # @TEST-EXEC: sleep 1
# @TEST-EXEC: btest-bg-run worker-1 HEAP_CHECK_DUMP_DIRECTORY=. HEAPCHECK=local BROPATH=$BROPATH:.. CLUSTER_NODE=worker-1 bro -m -r $TRACES/web.trace --pseudo-realtime %INPUT # @TEST-EXEC: btest-bg-run worker-1 HEAP_CHECK_DUMP_DIRECTORY=. HEAPCHECK=local BROPATH=$BROPATH:.. CLUSTER_NODE=worker-1 bro -m -r $TRACES/web.trace --pseudo-realtime %INPUT
# @TEST-EXEC: btest-bg-run worker-2 HEAP_CHECK_DUMP_DIRECTORY=. HEAPCHECK=local BROPATH=$BROPATH:.. CLUSTER_NODE=worker-2 bro -m -r $TRACES/web.trace --pseudo-realtime %INPUT # @TEST-EXEC: btest-bg-run worker-2 HEAP_CHECK_DUMP_DIRECTORY=. HEAPCHECK=local BROPATH=$BROPATH:.. CLUSTER_NODE=worker-2 bro -m -r $TRACES/web.trace --pseudo-realtime %INPUT

View file

@ -1,5 +1,7 @@
# Needs perftools support. # Needs perftools support.
# #
# @TEST-GROUP: leaks
#
# @TEST-REQUIRES: bro --help 2>&1 | grep -q mem-leaks # @TEST-REQUIRES: bro --help 2>&1 | grep -q mem-leaks
# #
# @TEST-EXEC: btest-bg-run sender HEAP_CHECK_DUMP_DIRECTORY=. HEAPCHECK=local bro -m --pseudo-realtime %INPUT ../sender.bro # @TEST-EXEC: btest-bg-run sender HEAP_CHECK_DUMP_DIRECTORY=. HEAPCHECK=local bro -m --pseudo-realtime %INPUT ../sender.bro

View 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