diff --git a/src/ip.cpp b/src/ip.cpp index bd9301e..7776395 100644 --- a/src/ip.cpp +++ b/src/ip.cpp @@ -432,6 +432,20 @@ bool IP::matches_response(const uint8_t *ptr, uint32_t total_sz) const { if(total_sz < sizeof(iphdr)) return false; const iphdr *ip_ptr = (const iphdr*)ptr; + // dest unreachable? + if(ip_ptr->protocol == Constants::IP::PROTO_ICMP) { + const uint8_t *pkt_ptr = ptr + sizeof(iphdr); + uint32_t pkt_sz = total_sz - sizeof(iphdr); + // It's an ICMP dest unreachable + if(pkt_sz > 4 && pkt_ptr[0] == 3) { + pkt_ptr += 4; + pkt_sz -= 4; + // If our IP header is in the ICMP payload, then it's the same packet. + // This keeps in mind checksum and IP identifier, so I guess it's enough. + if(pkt_sz >= sizeof(iphdr) && std::memcmp(&_ip, pkt_ptr, sizeof(iphdr))) + return true; + } + } // checks for broadcast addr if((_ip.saddr == ip_ptr->daddr && (_ip.daddr == ip_ptr->saddr || dst_addr().is_broadcast())) || (dst_addr().is_broadcast() && _ip.saddr == 0)) { diff --git a/tests/src/matches_response.cpp b/tests/src/matches_response.cpp index af57418..cc254e3 100644 --- a/tests/src/matches_response.cpp +++ b/tests/src/matches_response.cpp @@ -5,6 +5,7 @@ #include "udp.h" #include "dhcp.h" #include "dhcpv6.h" +#include "ip.h" using namespace Tins; @@ -33,6 +34,38 @@ TEST_F(MatchesResponseTest, TCPSynAck) { EXPECT_FALSE(sent.matches_response(syn_data, sizeof(syn_data))); } +TEST_F(MatchesResponseTest, UDPMatchesICMPResponse) { + const uint8_t udp_pkt[] = { + 69, 0, 0, 36, 44, 89, 64, 0, 64, 17, 140, 186, 192, 168, 0, 100, 192, + 168, 0, 1, 136, 167, 39, 15, 0, 16, 129, 215, 74, 69, 74, 69, 74, 69, + 74, 10 + }, + udp_pkt_resp[] = { + 69, 192, 0, 64, 150, 102, 0, 0, 64, 1, 97, 225, 192, 168, 0, 1, 192, + 168, 0, 100, 3, 3, 126, 212, 0, 0, 0, 0, 69, 0, 0, 36, 44, 89, 64, 0, + 64, 17, 140, 186, 192, 168, 0, 100, 192, 168, 0, 1, 136, 167, 39, 15, + 0, 16, 165, 135, 74, 69, 74, 69, 74, 69, 74, 10 + }; + IP ip(udp_pkt, sizeof(udp_pkt)); + EXPECT_TRUE(ip.matches_response(udp_pkt_resp, sizeof(udp_pkt_resp))); +} + +TEST_F(MatchesResponseTest, UDPMatchesICMPResponse2) { + const uint8_t udp_pkt[] = { + 69, 0, 0, 33, 0, 1, 0, 0, 128, 17, 185, 21, 192, 168, 0, 100, + 192, 168, 0, 1, 0, 0, 13, 5, 0, 13, 62, 59, 98, 111, 105, 110, + 103 + }, + udp_pkt_resp[] = { + 69, 192, 0, 61, 150, 255, 0, 0, 64, 1, 97, 75, 192, 168, 0, 1, + 192, 168, 0, 100, 3, 3, 126, 209, 0, 0, 0, 0, 69, 0, 0, 33, 0, + 1, 0, 0, 128, 17, 185, 21, 192, 168, 0, 100, 192, 168, 0, 1, 0, + 0, 13, 5, 0, 13, 62, 59, 98, 111, 105, 110, 103 + }; + IP ip(udp_pkt, sizeof(udp_pkt)); + EXPECT_TRUE(ip.matches_response(udp_pkt_resp, sizeof(udp_pkt_resp))); +} + TEST_F(MatchesResponseTest, DHCP) { uint8_t dhcp_discover[] = { 255, 255, 255, 255, 255, 255, 0, 1, 1, 0, 0, 1, 8, 0, 69, 0, 1,