mirror of
https://github.com/mfontanini/libtins
synced 2026-01-23 02:35:57 +01:00
Fixed bug on ICMP checksum calculation when using timestamp request/replies.
This commit is contained in:
13
src/icmp.cpp
13
src/icmp.cpp
@@ -57,10 +57,14 @@ ICMP::ICMP(const uint8_t *buffer, uint32_t total_sz)
|
||||
buffer += sizeof(icmphdr);
|
||||
total_sz -= sizeof(icmphdr);
|
||||
if(type() == TIMESTAMP_REQUEST || type() == TIMESTAMP_REPLY) {
|
||||
if(total_sz < sizeof(uint32_t) * 3)
|
||||
throw malformed_packet();
|
||||
const uint32_t *ptr = reinterpret_cast<const uint32_t*>(buffer);
|
||||
original_timestamp(*ptr++);
|
||||
receive_timestamp(*ptr++);
|
||||
transmit_timestamp(*ptr++);
|
||||
total_sz -= sizeof(uint32_t) * 3;
|
||||
buffer += sizeof(uint32_t) * 3;
|
||||
}
|
||||
if(total_sz)
|
||||
inner_pdu(new RawPDU(buffer, total_sz));
|
||||
@@ -183,17 +187,16 @@ void ICMP::write_serialization(uint8_t *buffer, uint32_t total_sz, const PDU *)
|
||||
*ptr++ = receive_timestamp();
|
||||
*ptr++ = transmit_timestamp();
|
||||
}
|
||||
|
||||
// checksum calc
|
||||
_icmp.check = 0;
|
||||
|
||||
uint32_t checksum = Utils::do_checksum(buffer + ICMP::header_size(), buffer + total_sz) +
|
||||
Utils::do_checksum((uint8_t*)&_icmp, ((uint8_t*)&_icmp) + ICMP::header_size());
|
||||
memcpy(buffer, &_icmp, sizeof(icmphdr));
|
||||
uint32_t checksum = Utils::do_checksum(buffer, buffer + total_sz);
|
||||
|
||||
while (checksum >> 16)
|
||||
checksum = (checksum & 0xffff) + (checksum >> 16);
|
||||
|
||||
_icmp.check = Endian::host_to_be<uint16_t>(~checksum);
|
||||
memcpy(buffer, &_icmp, sizeof(icmphdr));
|
||||
((icmphdr*)buffer)->check = _icmp.check;
|
||||
}
|
||||
|
||||
bool ICMP::matches_response(const uint8_t *ptr, uint32_t total_sz) const {
|
||||
|
||||
@@ -3,6 +3,8 @@
|
||||
#include <string>
|
||||
#include <stdint.h>
|
||||
#include "icmp.h"
|
||||
#include "ip.h"
|
||||
#include "ethernetII.h"
|
||||
#include "utils.h"
|
||||
|
||||
using namespace std;
|
||||
@@ -67,6 +69,19 @@ TEST_F(ICMPTest, FlagConstructor) {
|
||||
EXPECT_EQ(icmp.type(), ICMP::ECHO_REPLY);
|
||||
}
|
||||
|
||||
TEST_F(ICMPTest, ChecksumOnTimestamp) {
|
||||
const uint8_t raw_pkt[] = {
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 8, 0, 69, 0, 0, 45, 0, 1, 0,
|
||||
0, 128, 1, 185, 25, 192, 168, 0, 100, 192, 168, 0, 1, 13, 0, 237,
|
||||
141, 0, 0, 0, 0, 159, 134, 1, 0, 151, 134, 1, 0, 152, 134, 1, 0,
|
||||
98, 111, 105, 110, 103, 0
|
||||
};
|
||||
EthernetII pkt(raw_pkt, sizeof(raw_pkt));
|
||||
pkt.serialize();
|
||||
EXPECT_EQ(0xb919, pkt.rfind_pdu<IP>().checksum());
|
||||
EXPECT_EQ(0xed8d, pkt.rfind_pdu<ICMP>().check());
|
||||
}
|
||||
|
||||
TEST_F(ICMPTest, Code) {
|
||||
ICMP icmp;
|
||||
icmp.code(0x7a);
|
||||
|
||||
Reference in New Issue
Block a user