1
0
mirror of https://github.com/mfontanini/libtins synced 2026-01-23 02:35:57 +01:00

Always calculate IP checksum

Fixes #105
This commit is contained in:
Matias Fontanini
2015-11-08 10:25:49 -08:00
parent 87c4963533
commit 534bdaf30b
3 changed files with 52 additions and 7 deletions

View File

@@ -48,6 +48,13 @@ namespace Tins {
* By default, IP PDUs are initialized, setting TTL to IP::DEFAULT_TTL,
* id field to 1 and version to 4. Taking this into account, users
* should set destination and source port and would be enough to send one.
*
* When IP is the lowest layer on a packet, and the packet is serialized
* this willc heck if the source address is different than 0.0.0.0. If it is,
* the address of the interface in which the packet is going to be sent
* is retrieved (by using the routing table and the destination address)
* and set as the source address. If you don't want this behaviour, simply
* set the source address to 0.0.0.0.
*/
class IP : public PDU {
public:

View File

@@ -426,13 +426,11 @@ void IP::write_serialization(uint8_t *buffer, uint32_t total_sz, const PDU* pare
}
memset(buffer + sizeof(_ip) + _options_size, 0, _padded_options_size - _options_size);
if(parent) {
uint32_t check = Utils::do_checksum(buffer, buffer + sizeof(_ip) + _padded_options_size);
while (check >> 16)
check = (check & 0xffff) + (check >> 16);
checksum(~check);
((iphdr*)buffer)->check = _ip.check;
}
uint32_t check = Utils::do_checksum(buffer, buffer + sizeof(_ip) + _padded_options_size);
while (check >> 16)
check = (check & 0xffff) + (check >> 16);
checksum(~check);
((iphdr*)buffer)->check = _ip.check;
}
bool IP::matches_response(const uint8_t *ptr, uint32_t total_sz) const {

View File

@@ -26,6 +26,7 @@ public:
fragmented_ether_ip_packet[], tot_len_zero_packet[];
void test_equals(const IP &ip1, const IP &ip2);
void test_overwrite_source_address(IP& ip);
};
const uint8_t IPTest::expected_packet[] = {
@@ -718,3 +719,42 @@ TEST_F(IPTest, RemoveOption) {
PDU::serialization_type new_buffer = ip.serialize();
EXPECT_EQ(old_buffer, new_buffer);
}
void IPTest::test_overwrite_source_address(IP& ip) {
const uint8_t expected_output[] = {
69,0,0,40,0,1,0,0,128,6,38,186,1,2,3,4,8,8,8,8,0,32,0,12,0,
0,0,0,0,0,0,0,80,0,127,166,27,253,0,0
};
// Add TCP so we can check if the timestamp is correctly calculated
ip /= TCP(12, 32);
PDU::serialization_type buffer = ip.serialize();
EXPECT_EQ(IPv4Address("1.2.3.4"), ip.src_addr());
EXPECT_EQ(0x26ba, ip.checksum());
vector<uint8_t> output_buffer(expected_output,
expected_output + sizeof(expected_output));
EXPECT_EQ(output_buffer, buffer);
}
TEST_F(IPTest, OverwriteSourceAddress) {
IP ip("8.8.8.8");
ip.src_addr("1.2.3.4");
test_overwrite_source_address(ip);
}
TEST_F(IPTest, OverwriteSourceAddressUsingConstructor) {
IP ip("8.8.8.8", "1.2.3.4");
test_overwrite_source_address(ip);
}
TEST_F(IPTest, OverwriteSourceAddressConstructingFromBuffer) {
// Only the expected packet's IP layer
const uint8_t expected_output[] = {
69,0,0,20,0,1,0,0,128,0,0,0,1,2,3,4,8,8,8,8
};
IP ip(expected_output, sizeof(expected_output));
test_overwrite_source_address(ip);
}