From f30f4046328c4c769c850c37243ba4c95c94739c Mon Sep 17 00:00:00 2001 From: Matias Fontanini Date: Wed, 7 Sep 2011 09:52:58 -0300 Subject: [PATCH] Moved PDU::pseudoheader_checksum and PDU::do_checksum to Utils namespace. --- include/pdu.h | 21 --------------------- include/utils.h | 21 +++++++++++++++++++++ src/icmp.cpp | 3 ++- src/ip.cpp | 2 +- src/pdu.cpp | 27 --------------------------- src/udp.cpp | 4 ++-- src/utils.cpp | 25 +++++++++++++++++++++++++ 7 files changed, 51 insertions(+), 52 deletions(-) diff --git a/include/pdu.h b/include/pdu.h index 6149728..137c2ef 100644 --- a/include/pdu.h +++ b/include/pdu.h @@ -260,27 +260,6 @@ namespace Tins { * \param parent The PDU that's one level below this one on the stack. Might be 0. */ virtual void write_serialization(uint8_t *buffer, uint32_t total_sz, const PDU *parent) = 0; - - /** \brief Does the 16 bits sum of all 2 bytes elements between start and end. - * - * This is the checksum used by IP, UDP and TCP. If there's and odd number of - * bytes, the last one is padded and added to the checksum. The checksum is performed - * using network endiannes. - * \param start The pointer to the start of the buffer. - * \param end The pointer to the end of the buffer(excluding the last element). - * \return Returns the checksum between start and end(non inclusive). - */ - static uint32_t do_checksum(uint8_t *start, uint8_t *end); - - /** \brief Performs the pseudo header checksum used in TCP and UDP PDUs. - * - * \param source_ip The source ip address. - * \param dest_ip The destination ip address. - * \param len The length to be included in the pseudo header. - * \param flag The flag to use in the protocol field of the pseudo header. - * \return The pseudo header checksum. - */ - static uint32_t pseudoheader_checksum(uint32_t source_ip, uint32_t dest_ip, uint32_t len, uint32_t flag); private: uint32_t _flag; PDU *_inner_pdu; diff --git a/include/utils.h b/include/utils.h index 9c82b97..16f13f4 100644 --- a/include/utils.h +++ b/include/utils.h @@ -177,6 +177,27 @@ namespace Tins { */ uint16_t channel_to_mhz(uint16_t channel); + /** \brief Does the 16 bits sum of all 2 bytes elements between start and end. + * + * This is the checksum used by IP, UDP and TCP. If there's and odd number of + * bytes, the last one is padded and added to the checksum. The checksum is performed + * using network endiannes. + * \param start The pointer to the start of the buffer. + * \param end The pointer to the end of the buffer(excluding the last element). + * \return Returns the checksum between start and end(non inclusive). + */ + uint32_t do_checksum(uint8_t *start, uint8_t *end); + + /** \brief Performs the pseudo header checksum used in TCP and UDP PDUs. + * + * \param source_ip The source ip address. + * \param dest_ip The destination ip address. + * \param len The length to be included in the pseudo header. + * \param flag The flag to use in the protocol field of the pseudo header. + * \return The pseudo header checksum. + */ + uint32_t pseudoheader_checksum(uint32_t source_ip, uint32_t dest_ip, uint32_t len, uint32_t flag); + /** \brief Generic function to iterate through interface and collect * data. * diff --git a/src/icmp.cpp b/src/icmp.cpp index 52254b1..ff5e3c2 100644 --- a/src/icmp.cpp +++ b/src/icmp.cpp @@ -177,7 +177,8 @@ void Tins::ICMP::set_redirect(uint8_t icode, uint32_t address) { void Tins::ICMP::write_serialization(uint8_t *buffer, uint32_t total_sz, const PDU *) { assert(total_sz >= sizeof(icmphdr)); if(!_icmp.check) { - uint32_t checksum = PDU::do_checksum(buffer + sizeof(icmphdr), buffer + total_sz) + PDU::do_checksum((uint8_t*)&_icmp, ((uint8_t*)&_icmp) + sizeof(icmphdr)); + uint32_t checksum = Utils::do_checksum(buffer + sizeof(icmphdr), buffer + total_sz) + + Utils::do_checksum((uint8_t*)&_icmp, ((uint8_t*)&_icmp) + sizeof(icmphdr)); while (checksum >> 16) checksum = (checksum & 0xffff) + (checksum >> 16); _icmp.check = Utils::net_to_host_s(~checksum); diff --git a/src/ip.cpp b/src/ip.cpp index 16c7cc3..e955b1a 100644 --- a/src/ip.cpp +++ b/src/ip.cpp @@ -301,7 +301,7 @@ void Tins::IP::write_serialization(uint8_t *buffer, uint32_t total_sz, const PDU memset(buffer + sizeof(iphdr) + this->_options_size, 0, this->_padded_options_size - this->_options_size); if (parent && !_ip.check) { - uint32_t checksum = PDU::do_checksum(buffer, buffer + sizeof(iphdr) + _padded_options_size); + uint32_t checksum = Utils::do_checksum(buffer, buffer + sizeof(iphdr) + _padded_options_size); while (checksum >> 16) checksum = (checksum & 0xffff) + (checksum >> 16); ((iphdr*)buffer)->check = Utils::net_to_host_s(~checksum); diff --git a/src/pdu.cpp b/src/pdu.cpp index c5b8831..2ec2d40 100644 --- a/src/pdu.cpp +++ b/src/pdu.cpp @@ -102,30 +102,3 @@ Tins::PDU *Tins::PDU::clone_packet() const { } return ret; } - -/* Static methods */ -uint32_t Tins::PDU::do_checksum(uint8_t *start, uint8_t *end) { - uint32_t checksum(0); - uint16_t *ptr = (uint16_t*)start, *last = (uint16_t*)end, padding(0); - if(((end - start) & 1) == 1) { - last = (uint16_t*)end - 1; - padding = *(end - 1) << 8; - } - while(ptr < last) - checksum += Utils::net_to_host_s(*(ptr++)); - return checksum + padding; -} - -uint32_t Tins::PDU::pseudoheader_checksum(uint32_t source_ip, uint32_t dest_ip, uint32_t len, uint32_t flag) { - uint32_t checksum(0); - source_ip = Utils::net_to_host_l(source_ip); - dest_ip = Utils::net_to_host_l(dest_ip); - uint16_t *ptr = (uint16_t*)&source_ip; - - checksum += (uint32_t)(*ptr) + (uint32_t)(*(ptr+1)); - ptr = (uint16_t*)&dest_ip; - checksum += (uint32_t)(*ptr) + (uint32_t)(*(ptr+1)); - checksum += flag + len; - return checksum; -} - diff --git a/src/udp.cpp b/src/udp.cpp index 7f0ede3..161aa75 100644 --- a/src/udp.cpp +++ b/src/udp.cpp @@ -83,8 +83,8 @@ void Tins::UDP::write_serialization(uint8_t *buffer, uint32_t total_sz, const PD length(sizeof(udphdr) + inner_pdu()->size()); std::memcpy(buffer, &_udp, sizeof(udphdr)); if(!_udp.check && ip_packet) { - uint32_t checksum = PDU::pseudoheader_checksum(ip_packet->src_addr(), ip_packet->dst_addr(), size(), IPPROTO_UDP) + - PDU::do_checksum(buffer, buffer + total_sz); + uint32_t checksum = Utils::pseudoheader_checksum(ip_packet->src_addr(), ip_packet->dst_addr(), size(), IPPROTO_UDP) + + Utils::do_checksum(buffer, buffer + total_sz); while (checksum >> 16) checksum = (checksum & 0xffff)+(checksum >> 16); ((udphdr*)buffer)->check = Utils::net_to_host_s(~checksum); diff --git a/src/utils.cpp b/src/utils.cpp index adcc1ce..83bc2bc 100644 --- a/src/utils.cpp +++ b/src/utils.cpp @@ -252,6 +252,31 @@ uint16_t Tins::Utils::channel_to_mhz(uint16_t channel) { return 2407 + (channel * 5); } +uint32_t Tins::Utils::do_checksum(uint8_t *start, uint8_t *end) { + uint32_t checksum(0); + uint16_t *ptr = (uint16_t*)start, *last = (uint16_t*)end, padding(0); + if(((end - start) & 1) == 1) { + last = (uint16_t*)end - 1; + padding = *(end - 1) << 8; + } + while(ptr < last) + checksum += Utils::net_to_host_s(*(ptr++)); + return checksum + padding; +} + +uint32_t Tins::Utils::pseudoheader_checksum(uint32_t source_ip, uint32_t dest_ip, uint32_t len, uint32_t flag) { + uint32_t checksum(0); + source_ip = Utils::net_to_host_l(source_ip); + dest_ip = Utils::net_to_host_l(dest_ip); + uint16_t *ptr = (uint16_t*)&source_ip; + + checksum += (uint32_t)(*ptr) + (uint32_t)(*(ptr+1)); + ptr = (uint16_t*)&dest_ip; + checksum += (uint32_t)(*ptr) + (uint32_t)(*(ptr+1)); + checksum += flag + len; + return checksum; +} + uint32_t Tins::Utils::crc32(uint8_t* data, uint32_t data_size) { uint32_t i, crc = 0; static uint32_t crc_table[] = {