diff --git a/include/ip.h b/include/ip.h index 93ee269..4a173ac 100644 --- a/include/ip.h +++ b/include/ip.h @@ -307,7 +307,7 @@ namespace Tins { * * \return The checksum for this IP PDU. */ - uint16_t check() const { return Endian::be_to_host(_ip.check); } + uint16_t checksum() const { return Endian::be_to_host(_ip.check); } /** * \brief Getter for the source address field. @@ -385,13 +385,6 @@ namespace Tins { */ void protocol(uint8_t new_protocol); - /** - * \brief Setter for the checksum field. - * - * \param new_check The new checksum. - */ - void check(uint16_t new_check); - /** * \brief Setter for the source address field. * @@ -632,6 +625,7 @@ namespace Tins { uint8_t* write_option(const option &opt, uint8_t* buffer); void add_route_option(option_identifier id, const generic_route_option_type &data); generic_route_option_type search_route_option(option_identifier id) const; + void checksum(uint16_t new_check); iphdr _ip; uint16_t _options_size, _padded_options_size; diff --git a/include/tcp.h b/include/tcp.h index 78acbe8..ea0a87c 100644 --- a/include/tcp.h +++ b/include/tcp.h @@ -178,7 +178,7 @@ namespace Tins { * * \return The checksum field in an uint16_t. */ - uint16_t check() const { return Endian::be_to_host(_tcp.check); } + uint16_t checksum() const { return Endian::be_to_host(_tcp.check); } /** * \brief Getter for the urgent pointer field. @@ -246,13 +246,6 @@ namespace Tins { */ void window(uint16_t new_window); - /** - * \brief Setter for the checksum field. - * - * \param new_check The new checksum. - */ - void check(uint16_t new_check); - /** * \brief Setter for the urgent pointer field. * @@ -466,6 +459,7 @@ namespace Tins { void internal_add_option(const option &option); void write_serialization(uint8_t *buffer, uint32_t total_sz, const PDU *parent); + void checksum(uint16_t new_check); uint8_t *write_option(const option &opt, uint8_t *buffer); diff --git a/include/udp.h b/include/udp.h index f43b9fc..780c3bd 100644 --- a/include/udp.h +++ b/include/udp.h @@ -89,6 +89,12 @@ namespace Tins { * \return The length of the datagram. */ uint16_t length() const { return Endian::be_to_host(_udp.len); } + + /** + * \brief Getter for the checksum of the datagram. + * \return The datagram's checksum. + */ + uint16_t checksum() const { return Endian::be_to_host(_udp.check); } /** * \brief Set the destination port. diff --git a/src/ip.cpp b/src/ip.cpp index 8c05ff6..914a439 100644 --- a/src/ip.cpp +++ b/src/ip.cpp @@ -173,7 +173,7 @@ void IP::protocol(uint8_t new_protocol) { _ip.protocol = new_protocol; } -void IP::check(uint16_t new_check) { +void IP::checksum(uint16_t new_check) { _ip.check = Endian::host_to_be(new_check); } @@ -385,7 +385,7 @@ void IP::write_serialization(uint8_t *buffer, uint32_t total_sz, const PDU* pare #ifdef TINS_DEBUG assert(total_sz >= my_sz); #endif - check(0); + checksum(0); if(inner_pdu()) { uint32_t new_flag; switch(inner_pdu()->pdu_type()) { @@ -425,10 +425,10 @@ 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 checksum = Utils::do_checksum(buffer, buffer + sizeof(_ip) + _padded_options_size); - while (checksum >> 16) - checksum = (checksum & 0xffff) + (checksum >> 16); - check(~checksum); + 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; } } diff --git a/src/tcp.cpp b/src/tcp.cpp index e84058b..b6f4351 100644 --- a/src/tcp.cpp +++ b/src/tcp.cpp @@ -116,7 +116,7 @@ void TCP::window(uint16_t new_window) { _tcp.window = Endian::host_to_be(new_window); } -void TCP::check(uint16_t new_check) { +void TCP::checksum(uint16_t new_check) { _tcp.check = Endian::host_to_be(new_check); } @@ -281,7 +281,7 @@ uint32_t TCP::header_size() const { void TCP::write_serialization(uint8_t *buffer, uint32_t total_sz, const PDU *parent) { assert(total_sz >= header_size()); uint8_t *tcp_start = buffer; - check(0); + checksum(0); buffer += sizeof(tcphdr); _tcp.doff = (sizeof(tcphdr) + _total_options_size) / sizeof(uint32_t); for(options_type::iterator it = _options.begin(); it != _options.end(); ++it) @@ -299,25 +299,25 @@ void TCP::write_serialization(uint8_t *buffer, uint32_t total_sz, const PDU *par const Tins::IP *ip_packet = dynamic_cast(parent); if(ip_packet) { - uint32_t checksum = Utils::pseudoheader_checksum(ip_packet->src_addr(), + uint32_t check = Utils::pseudoheader_checksum(ip_packet->src_addr(), ip_packet->dst_addr(), size(), Constants::IP::PROTO_TCP) + Utils::do_checksum(tcp_start, tcp_start + total_sz); - while (checksum >> 16) - checksum = (checksum & 0xffff) + (checksum >> 16); - check(~checksum); + while (check >> 16) + check = (check & 0xffff) + (check >> 16); + checksum(~check); ((tcphdr*)tcp_start)->check = _tcp.check; } else { const Tins::IPv6 *ipv6_packet = dynamic_cast(parent); if(ipv6_packet) { - uint32_t checksum = Utils::pseudoheader_checksum(ipv6_packet->src_addr(), + uint32_t check = Utils::pseudoheader_checksum(ipv6_packet->src_addr(), ipv6_packet->dst_addr(), size(), Constants::IP::PROTO_TCP) + Utils::do_checksum(tcp_start, tcp_start + total_sz); - while (checksum >> 16) - checksum = (checksum & 0xffff) + (checksum >> 16); - check(~checksum); + while (check >> 16) + check = (check & 0xffff) + (check >> 16); + checksum(~check); ((tcphdr*)tcp_start)->check = _tcp.check; } } diff --git a/tests/src/ip.cpp b/tests/src/ip.cpp index efb9eb9..1d95a0e 100644 --- a/tests/src/ip.cpp +++ b/tests/src/ip.cpp @@ -105,12 +105,6 @@ TEST_F(IPTest, Protocol) { EXPECT_EQ(ip.protocol(), 0x7f); } -TEST_F(IPTest, Check) { - IP ip; - ip.check(0x7f1a); - EXPECT_EQ(ip.check(), 0x7f1a); -} - TEST_F(IPTest, SrcIPString) { IP ip; string string_ip("192.155.32.10"); diff --git a/tests/src/tcp.cpp b/tests/src/tcp.cpp index b87840b..63f7ac7 100644 --- a/tests/src/tcp.cpp +++ b/tests/src/tcp.cpp @@ -4,6 +4,7 @@ #include #include #include "tcp.h" +#include "ip.h" #include "utils.h" using namespace std; @@ -11,7 +12,7 @@ using namespace Tins; class TCPTest : public testing::Test { public: - static const uint8_t expected_packet[]; + static const uint8_t expected_packet[], checksum_packet[]; void test_equals(const TCP &tcp1, const TCP &tcp2); }; @@ -22,6 +23,13 @@ const uint8_t TCPTest::expected_packet[] = { 18, 52, 3, 3, 122, 4, 2, 5, 10, 0, 1, 2, 3, 4, 5, 6, 7, 0, 0, 0 }; +// IP + TCP +const uint8_t TCPTest::checksum_packet[] = { + 69, 0, 0, 40, 0, 0, 64, 0, 64, 6, 60, 206, 0, 0, 0, 0, 127, 0, 0, 1, + 5, 57, 199, 49, 0, 0, 0, 0, 255, 216, 70, 222, 80, 20, 0, 0, 158, 172, + 0, 0 +}; + TEST_F(TCPTest, DefaultConstructor) { TCP tcp; @@ -30,6 +38,19 @@ TEST_F(TCPTest, DefaultConstructor) { EXPECT_EQ(tcp.pdu_type(), PDU::TCP); } +TEST_F(TCPTest, ChecksumCheck) { + IP pkt1(checksum_packet, sizeof(checksum_packet)); + const TCP &tcp1 = pkt1.rfind_pdu(); + uint16_t checksum = tcp1.checksum(); + + IP::serialization_type buffer = pkt1.serialize(); + IP pkt2(&buffer[0], buffer.size()); + const TCP &tcp2 = pkt2.rfind_pdu(); + EXPECT_EQ(checksum, tcp2.checksum()); + EXPECT_EQ(tcp1.checksum(), tcp2.checksum()); + +} + TEST_F(TCPTest, CopyConstructor) { TCP tcp1(0x6d1f, 0x78f2); TCP tcp2(tcp1); @@ -86,12 +107,6 @@ TEST_F(TCPTest, Window) { EXPECT_EQ(tcp.window(), 0x5fad); } -TEST_F(TCPTest, Check) { - TCP tcp; - tcp.check(0x5fad); - EXPECT_EQ(tcp.check(), 0x5fad); -} - TEST_F(TCPTest, UrgPtr) { TCP tcp; tcp.urg_ptr(0x5fad); @@ -166,7 +181,7 @@ void TCPTest::test_equals(const TCP &tcp1, const TCP &tcp2) { EXPECT_EQ(tcp1.seq(), tcp2.seq()); EXPECT_EQ(tcp1.ack_seq(), tcp2.ack_seq()); EXPECT_EQ(tcp1.window(), tcp2.window()); - EXPECT_EQ(tcp1.check(), tcp2.check()); + EXPECT_EQ(tcp1.checksum(), tcp2.checksum()); EXPECT_EQ(tcp1.urg_ptr(), tcp2.urg_ptr()); EXPECT_EQ(tcp1.data_offset(), tcp2.data_offset()); EXPECT_EQ((bool)tcp1.inner_pdu(), (bool)tcp2.inner_pdu()); diff --git a/tests/src/udp.cpp b/tests/src/udp.cpp index 4f3f2d5..afc91fa 100644 --- a/tests/src/udp.cpp +++ b/tests/src/udp.cpp @@ -2,7 +2,7 @@ #include #include #include "udp.h" -#include "pdu.h" +#include "ip.h" using namespace std; @@ -11,7 +11,7 @@ using namespace Tins; class UDPTest : public testing::Test { public: - static const uint8_t expected_packet[]; + static const uint8_t expected_packet[], checksum_packet[]; void test_equals(const UDP& udp1, const UDP& udp2); }; @@ -20,6 +20,12 @@ const uint8_t UDPTest::expected_packet[] = { 245, 26, 71, 241, 8, 0, 0, 0 }; +const uint8_t UDPTest::checksum_packet[] = { + 69, 0, 0, 48, 35, 109, 64, 0, 64, 17, 25, 78, 0, 0, 0, 0, 127, 0, 0, + 1, 5, 57, 155, 11, 0, 28, 84, 167, 97, 115, 100, 97, 115, 100, 115, + 97, 115, 100, 97, 115, 100, 115, 97, 100, 97, 115, 100, 10 +}; + void UDPTest::test_equals(const UDP& udp1, const UDP& udp2) { EXPECT_EQ(udp1.dport(), udp2.dport()); @@ -37,6 +43,18 @@ TEST_F(UDPTest, DefaultContructor) { EXPECT_FALSE(udp.inner_pdu()); } +TEST_F(UDPTest, ChecksumCheck) { + IP pkt1(checksum_packet, sizeof(checksum_packet)); + const UDP &udp1 = pkt1.rfind_pdu(); + uint16_t checksum = udp1.checksum(); + + IP::serialization_type buffer = pkt1.serialize(); + IP pkt2(&buffer[0], buffer.size()); + const UDP &udp2 = pkt2.rfind_pdu(); + EXPECT_EQ(checksum, udp2.checksum()); + EXPECT_EQ(udp1.checksum(), udp2.checksum()); +} + TEST_F(UDPTest, CopyContructor) { UDP udp1(expected_packet, sizeof(expected_packet)); UDP udp2(udp1);