diff --git a/src/Sessions.cc b/src/Sessions.cc index c86395267b..5eb83ffcd8 100644 --- a/src/Sessions.cc +++ b/src/Sessions.cc @@ -251,7 +251,7 @@ void NetSessions::DoNextPacket(double t, const Packet* pkt, const IP_Hdr* ip_hdr if ( packet_filter && packet_filter->Match(ip_hdr, len, caplen) ) return; - if ( ! ignore_checksums && ip4 && + if ( ! pkt->l2_checksummed && ! ignore_checksums && ip4 && ones_complement_checksum((void*) ip4, ip_hdr_len, 0) != 0xffff ) { Weird("bad_IP_checksum", pkt, encapsulation); diff --git a/src/analyzer/protocol/icmp/ICMP.cc b/src/analyzer/protocol/icmp/ICMP.cc index 145c00dfee..eed57d1e17 100644 --- a/src/analyzer/protocol/icmp/ICMP.cc +++ b/src/analyzer/protocol/icmp/ICMP.cc @@ -333,7 +333,7 @@ RecordVal* ICMP_Analyzer::ExtractICMP4Context(int len, const u_char*& data) { bad_hdr_len = 0; ip_len = ip_hdr->TotalLen(); - bad_checksum = (ones_complement_checksum((void*) ip_hdr->IP4_Hdr(), ip_hdr_len, 0) != 0xffff); + bad_checksum = ! current_pkt->l3_checksummed && (ones_complement_checksum((void*) ip_hdr->IP4_Hdr(), ip_hdr_len, 0) != 0xffff); src_addr = ip_hdr->SrcAddr(); dst_addr = ip_hdr->DstAddr(); diff --git a/src/analyzer/protocol/tcp/TCP.cc b/src/analyzer/protocol/tcp/TCP.cc index a19f425df3..640c065dfd 100644 --- a/src/analyzer/protocol/tcp/TCP.cc +++ b/src/analyzer/protocol/tcp/TCP.cc @@ -275,7 +275,7 @@ const struct tcphdr* TCP_Analyzer::ExtractTCP_Header(const u_char*& data, bool TCP_Analyzer::ValidateChecksum(const struct tcphdr* tp, TCP_Endpoint* endpoint, int len, int caplen) { - if ( ! ignore_checksums && caplen >= len && + if ( ! current_pkt->l3_checksummed && ! ignore_checksums && caplen >= len && ! endpoint->ValidChecksum(tp, len) ) { Weird("bad_TCP_checksum"); diff --git a/src/analyzer/protocol/udp/UDP.cc b/src/analyzer/protocol/udp/UDP.cc index 06a971398d..c9b9d84b2c 100644 --- a/src/analyzer/protocol/udp/UDP.cc +++ b/src/analyzer/protocol/udp/UDP.cc @@ -62,7 +62,7 @@ void UDP_Analyzer::DeliverPacket(int len, const u_char* data, bool is_orig, int chksum = up->uh_sum; - auto validate_checksum = ! ignore_checksums && caplen >=len; + auto validate_checksum = ! current_pkt->l3_checksummed && ! ignore_checksums && caplen >=len; constexpr auto vxlan_len = 8; constexpr auto eth_len = 14; diff --git a/src/iosource/Packet.cc b/src/iosource/Packet.cc index 0195f18be4..2a8c39ab8a 100644 --- a/src/iosource/Packet.cc +++ b/src/iosource/Packet.cc @@ -52,6 +52,9 @@ void Packet::Init(int arg_link_type, pkt_timeval *arg_ts, uint32_t arg_caplen, l2_valid = false; + l2_checksummed = false; + l3_checksummed = false; + if ( data && cap_len < hdr_size ) { Weird("truncated_link_header"); @@ -677,4 +680,3 @@ void Packet::Describe(ODesc* d) const d->Add("->"); d->Add(ip.DstAddr()); } - diff --git a/src/iosource/Packet.h b/src/iosource/Packet.h index 79e82c3227..be6d6d0f7f 100644 --- a/src/iosource/Packet.h +++ b/src/iosource/Packet.h @@ -199,6 +199,18 @@ public: */ uint32_t inner_vlan; + /** + * Indicates whether the layer 2 checksum was validated by the + * hardware/kernel before being received by zeek. + */ + bool l2_checksummed; + + /** + * Indicates whether the layer 3 checksum was validated by the + * hardware/kernel before being received by zeek. + */ + bool l3_checksummed; + private: // Calculate layer 2 attributes. Sets void ProcessLayer2();