Add more icmpv6 events, and general code cleanup

This commit is contained in:
Daniel Thayer 2012-03-02 12:29:18 -06:00
parent e9728d82ab
commit 6eb9f63e17
7 changed files with 164 additions and 54 deletions

View file

@ -20,8 +20,7 @@ namespace AnalyzerTag {
PIA_TCP, PIA_UDP,
// Transport-layer analyzers.
ICMP,
TCP, UDP,
ICMP, TCP, UDP,
// Application-layer analyzers (hand-written).
BitTorrent, BitTorrentTracker,

View file

@ -52,10 +52,10 @@ void ICMP_Analyzer::DeliverPacket(int len, const u_char* data,
assert(caplen >= len); // Should have been caught earlier already.
if ( ! ignore_checksums )
{
int chksum = 0;
{
int chksum = 0;
switch ( ip->NextProto() )
switch ( ip->NextProto() )
{
case IPPROTO_ICMP:
chksum = icmp_checksum(icmpp, len);
@ -69,11 +69,11 @@ void ICMP_Analyzer::DeliverPacket(int len, const u_char* data,
reporter->InternalError("unexpected IP proto in ICMP analyzer");
}
if ( chksum != 0xffff )
{
Weird("bad_ICMP6_checksum");
return;
}
if ( chksum != 0xffff )
{
Weird("bad_ICMP_checksum");
return;
}
}
Conn()->SetLastTime(current_timestamp);
@ -147,6 +147,8 @@ void ICMP_Analyzer::NextICMP6(double t, const struct icmp* icmpp, int len, int c
break;
// Router related messages.
case ND_NEIGHBOR_SOLICIT:
case ND_NEIGHBOR_ADVERT:
case ND_REDIRECT:
case ND_ROUTER_SOLICIT:
case ICMP6_ROUTER_RENUMBERING:
@ -156,17 +158,9 @@ void ICMP_Analyzer::NextICMP6(double t, const struct icmp* icmpp, int len, int c
#if 0
// Currently not specifically implemented.
case ICMP6_PARAM_PROB:
case MLD_LISTENER_QUERY:
case MLD_LISTENER_REPORT:
case MLD_LISTENER_REDUCTION:
case ND_NEIGHBOR_SOLICIT:
case ND_NEIGHBOR_ADVERT:
case ND_REDIRECT:
case ICMP6_ROUTER_RENUMBERING:
case ND_NEIGHBOR_SOLICIT:
case ND_NEIGHBOR_ADVERT:
case ICMP6_TIME_EXCEEDED:
#endif
default:
ICMPEvent(icmp_sent, icmpp, len, 1);
@ -221,7 +215,7 @@ TransportProto ICMP_Analyzer::GetContextProtocol(const IP_Hdr* ip_hdr, uint32* s
case 1: proto = TRANSPORT_ICMP; break;
case 6: proto = TRANSPORT_TCP; break;
case 17: proto = TRANSPORT_UDP; break;
case 58: proto = TRANSPORT_ICMP; //TransportProto Hack // XXX What's this?
case 58: proto = TRANSPORT_ICMP; break;
default: proto = TRANSPORT_UNKNOWN; break;
}
@ -386,15 +380,8 @@ RecordVal* ICMP_Analyzer::ExtractICMP6Context(int len, const u_char*& data)
iprec->Assign(0, id_val);
iprec->Assign(1, new Val(ip_len, TYPE_COUNT));
//TransportProto Hack // XXX Likewise.
if ( ip_hdr->NextProto() == 58 || 17 ) //if the encap packet is ICMPv6 we force this... (cause there is no IGMP (by that name) for ICMPv6), rather ugly hack once more
{
iprec->Assign(2, new Val(58, TYPE_COUNT));
}
else
{
iprec->Assign(2, new Val(proto, TYPE_COUNT));
}
//if the encap packet is ICMPv6 we force this... (cause there is no IGMP (by that name) for ICMPv6), rather ugly hack once more
iprec->Assign(2, new Val(58, TYPE_COUNT));
iprec->Assign(3, new Val(bad_hdr_len, TYPE_BOOL));
@ -509,12 +496,21 @@ void ICMP_Analyzer::Router(double t, const struct icmp* icmpp, int len,
switch ( icmpp->icmp_type )
{
case ND_NEIGHBOR_ADVERT:
f = icmp_neighbor_advertisement;
break;
case ND_NEIGHBOR_SOLICIT:
f = icmp_neighbor_solicitation;
break;
case ND_ROUTER_ADVERT:
f = icmp_router_advertisement;
break;
case ND_REDIRECT:
case ND_ROUTER_SOLICIT:
f = icmp_router_solicitation;
break;
case ND_REDIRECT:
f = icmp_redirect;
break;
case ICMP6_ROUTER_RENUMBERING:
default:
ICMPEvent(icmp_sent, icmpp, len, 1);
@ -567,11 +563,14 @@ void ICMP_Analyzer::Context6(double t, const struct icmp* icmpp,
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_error_message;
f = icmp_packet_too_big;
break;
}

View file

@ -310,8 +310,6 @@ void NetSessions::NextPacketSecondary(double /* t */, const struct pcap_pkthdr*
++num_packets_processed;
uint32 caplen = hdr->caplen - hdr_size;
if ( caplen < sizeof(struct ip) )
{
@ -446,7 +444,7 @@ void NetSessions::DoNextPacket(double t, const struct pcap_pkthdr* hdr,
int proto = ip_hdr->NextProto();
if ( proto != IPPROTO_TCP && proto != IPPROTO_UDP &&
proto != IPPROTO_ICMP && proto != IPPROTO_ICMPV6) // Added ICMPV6, Matti
proto != IPPROTO_ICMP && proto != IPPROTO_ICMPV6)
{
dump_this_packet = 1;
return;
@ -489,7 +487,7 @@ void NetSessions::DoNextPacket(double t, const struct pcap_pkthdr* hdr,
caplen -= ip_hdr_len;
uint32 min_hdr_len = (proto == IPPROTO_TCP) ? sizeof(struct tcphdr) :
(proto == IPPROTO_UDP ? sizeof(struct udphdr) : ICMP_MINLEN); //needs checking for ICMPV6?, Matti
(proto == IPPROTO_UDP ? sizeof(struct udphdr) : ICMP_MINLEN);
if ( len < min_hdr_len )
{
@ -550,12 +548,11 @@ void NetSessions::DoNextPacket(double t, const struct pcap_pkthdr* hdr,
break;
}
case IPPROTO_ICMPV6: // new case, identical to ICMP, is this correct?? Matti
case IPPROTO_ICMPV6:
{
const struct icmp* icmpp = (const struct icmp *) data;
id.src_port = icmpp->icmp_type;
//printf("TYPE: %d\n", id.src_port); //testing, Matti
id.dst_port = ICMP6_counterpart(icmpp->icmp_type,
icmpp->icmp_code,
id.is_one_way);
@ -565,8 +562,8 @@ void NetSessions::DoNextPacket(double t, const struct pcap_pkthdr* hdr,
d = &icmp_conns;
break;
}
default:
Weird(fmt("unknown_protocol %d", proto), hdr, pkt);
return;
@ -735,13 +732,11 @@ Val* NetSessions::BuildHeader(const struct ip* ip)
break;
}
case IPPROTO_ICMPV6: //Added, Matti
case IPPROTO_ICMPV6:
{
const struct icmp* icmpp = (const struct icmp *) data;
RecordVal* icmp_hdr = new RecordVal(icmp_hdr_type);
//printf("datalen:%d",data_len); //Testing, Matti
icmp_hdr->Assign(0, new Val(icmpp->icmp_type, TYPE_COUNT));
pkt_hdr->Assign(3, icmp_hdr);
@ -1065,7 +1060,7 @@ Connection* NetSessions::NewConn(HashKey* k, double t, const ConnID* id,
case IPPROTO_UDP:
tproto = TRANSPORT_UDP;
break;
case IPPROTO_ICMPV6: //TransportProto Hack
case IPPROTO_ICMPV6:
tproto = TRANSPORT_ICMP;
break;
default:
@ -1150,6 +1145,7 @@ bool NetSessions::IsLikelyServerPort(uint32 port, TransportProto proto) const
port |= UDP_PORT_MASK;
else if ( proto == TRANSPORT_ICMP )
port |= ICMP_PORT_MASK;
return port_cache.find(port) != port_cache.end();
}

View file

@ -788,6 +788,7 @@ PortVal::PortVal(uint32 p, TransportProto port_type) : Val(TYPE_PORT)
case TRANSPORT_ICMP:
p |= ICMP_PORT_MASK;
break;
default:
break; // "other"
}

View file

@ -534,7 +534,6 @@ public:
int IsUDP() const;
int IsICMP() const;
TransportProto PortType() const
{
if ( IsTCP() )

View file

@ -798,6 +798,24 @@ event icmp_echo_request%(c: connection, icmp: icmp_conn, id: count, seq: count,
## icmp_time_exceeded icmp_unreachable
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.
##
## See `Wikipedia
@ -821,13 +839,28 @@ event icmp_echo_reply%(c: connection, icmp: icmp_conn, id: count, seq: count, pa
## icmp_time_exceeded
event icmp_unreachable%(c: connection, icmp: icmp_conn, code: count, context: icmp_context%);
event icmp_error_message%(c: connection, icmp: icmp_conn, code: count, context: icmp_context%);
event icmp_router_advertisement%(c: connection, icmp: icmp_conn%);
event icmp6_placeholder%(c: connection, icmp: icmp_conn, ICMP6: bool%);
## 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.
##
@ -852,6 +885,89 @@ event icmp6_placeholder%(c: connection, icmp: icmp_conn, ICMP6: bool%);
## icmp_unreachable
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%);
## 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%);
## 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%);
## Generated for ICMP *redirect* messages.
##
## See `Wikipedia

View file

@ -90,7 +90,7 @@ int udp_checksum(const struct ip* ip, const struct udphdr* up, int len)
int udp6_checksum(const struct ip6_hdr* ip6, const struct udphdr* up, int len)
{
// UDP over IPv6 uses the same checksum function as over IPv4 but a
// different pseuod-header over which it is computed.
// different pseudo-header over which it is computed.
uint32 sum;
if ( len % 2 == 1 )
@ -116,8 +116,8 @@ int udp6_checksum(const struct ip6_hdr* ip6, const struct udphdr* up, int len)
int icmp6_checksum(const struct icmp* icmpp, const struct ip6_hdr* ip6, int len)
{
// ICMP6 uses the same checksum function as over ICMP4 but a different
// pseuod-header over which it is computed.
// ICMP6 uses the same checksum function as ICMP4 but a different
// pseudo-header over which it is computed.
uint32 sum;
if ( len % 2 == 1 )