mirror of
https://github.com/mfontanini/libtins
synced 2026-01-23 02:35:57 +01:00
@@ -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:
|
||||
|
||||
12
src/ip.cpp
12
src/ip.cpp
@@ -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 {
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
|
||||
|
||||
|
||||
Reference in New Issue
Block a user