From d1ed469225d5192e168657585a4dce0a67d2f714 Mon Sep 17 00:00:00 2001 From: Guilherme Maciel Ferreira Date: Fri, 25 Feb 2011 11:56:32 +0100 Subject: [PATCH] Refactored the checksum calculation and IcmpHeader class - Included the checksum in the IcmpHeader constructor - Created a type for ICMP package body, namely Icmpbody - Transformed the compute_checksum template function into a template class, ChecksumCalculator, and defined an specialization type, namely IcmpChecksumCalculator --- src/ping/boostpinger.cpp | 20 ++++++----- src/ping/checksumcalculator.h | 70 +++++++++++++++++++++++++++++++++++++ src/ping/icmpbody.h | 12 ++++++ src/ping/icmpchecksumcalculator.h | 13 +++++++ src/ping/icmpheader.h | 29 +-------------- 5 files changed, 108 insertions(+), 36 deletions(-) create mode 100644 src/ping/checksumcalculator.h create mode 100644 src/ping/icmpbody.h create mode 100644 src/ping/icmpchecksumcalculator.h diff --git a/src/ping/boostpinger.cpp b/src/ping/boostpinger.cpp index 605b43f..00497c9 100644 --- a/src/ping/boostpinger.cpp +++ b/src/ping/boostpinger.cpp @@ -7,7 +7,9 @@ #include #include -#include "icmp_header.h" +#include "icmpbody.h" +#include "icmpchecksumcalculator.h" +#include "icmpheader.h" #include "ipv4_header.h" #include "boostpinger.h" @@ -47,17 +49,17 @@ void BoostPinger::ping( const Host &host ) void BoostPinger::start_send() { - std::string body( "ping message" ); + IcmpBody body( "ping message" ); // Create an ICMP header for an echo request. + SequenceNumber++; - IcmpHeader echo_request( - IcmpHeader::EchoRequest, - 0, - get_identifier(), - SequenceNumber - ); - compute_checksum( echo_request, body.begin(), body.end() ); + IcmpHeader::IcmpType type = IcmpHeader::EchoRequest; + uint8_t code = 0; + uint16_t identifier = get_identifier(); + IcmpChecksumCalculator calculator( body.begin(), body.end() ); + uint16_t checksum = calculator.compute( type, code, identifier, SequenceNumber ); + IcmpHeader echo_request( type, code, checksum, identifier, SequenceNumber ); // Encode the request packet. boost::asio::streambuf request_buffer; diff --git a/src/ping/checksumcalculator.h b/src/ping/checksumcalculator.h new file mode 100644 index 0000000..9b5b657 --- /dev/null +++ b/src/ping/checksumcalculator.h @@ -0,0 +1,70 @@ +#ifndef CHECKSUMCALCULATOR_H +#define CHECKSUMCALCULATOR_H + +#include + +//----------------------------------------------------------------------------- +// ChecksumCalculator +//----------------------------------------------------------------------------- + +template +class ChecksumCalculator +{ +public: + ChecksumCalculator( + Iterator body_begin, + Iterator body_end + ); + + uint16_t compute( + uint8_t type, + uint8_t code, + uint16_t identifier, + uint16_t sequence_number + ); + +private: + Iterator body_begin; + Iterator body_end; + +}; + +template + ChecksumCalculator::ChecksumCalculator( + Iterator body_begin, + Iterator body_end + ) : + body_begin(), + body_end() + { + this->body_begin = body_begin; + this->body_end = body_end; + } + +template + uint16_t ChecksumCalculator::compute( + uint8_t type, + uint8_t code, + uint16_t identifier, + uint16_t sequence_number + ) + { + uint32_t sum = (type << 8) + code + identifier + sequence_number; + + Iterator body_iter = body_begin; + while ( body_iter != body_end ) + { + sum += (static_cast ( *body_iter++ ) << 8); + if ( body_iter != body_end ) + sum += static_cast ( *body_iter++ ); + } + + sum = (sum >> 16) + (sum & 0xFFFF); + sum += (sum >> 16); + + uint16_t checksum = static_cast ( ~sum ); + + return checksum; + } + +#endif /* CHECKSUMCALCULATOR_H */ diff --git a/src/ping/icmpbody.h b/src/ping/icmpbody.h new file mode 100644 index 0000000..0878949 --- /dev/null +++ b/src/ping/icmpbody.h @@ -0,0 +1,12 @@ +#ifndef ICMPBODY_H +#define ICMPBODY_H + +#include + +//----------------------------------------------------------------------------- +// IcmpBody +//----------------------------------------------------------------------------- + +typedef std::string IcmpBody; + +#endif /* ICMPBODY_H */ diff --git a/src/ping/icmpchecksumcalculator.h b/src/ping/icmpchecksumcalculator.h new file mode 100644 index 0000000..9d475bf --- /dev/null +++ b/src/ping/icmpchecksumcalculator.h @@ -0,0 +1,13 @@ +#ifndef ICMPCHECKSUMCALCULATOR_H +#define ICMPCHECKSUMCALCULATOR_H + +#include "checksumcalculator.h" +#include "icmpbody.h" + +//----------------------------------------------------------------------------- +// IcmpChecksumCalculator +//----------------------------------------------------------------------------- + +typedef ChecksumCalculator IcmpChecksumCalculator; + +#endif /* ICMPCHECKSUMCALCULATOR_H */ diff --git a/src/ping/icmpheader.h b/src/ping/icmpheader.h index 7a7984f..61e1b0e 100644 --- a/src/ping/icmpheader.h +++ b/src/ping/icmpheader.h @@ -1,7 +1,6 @@ #ifndef ICMP_HEADER_HPP #define ICMP_HEADER_HPP -#include #include #include #include @@ -48,6 +47,7 @@ public: IcmpHeader( IcmpType type, uint8_t code, + uint16_t checksum, uint16_t identifier, uint16_t sequence_number ); @@ -79,32 +79,7 @@ private: void encode( int a, int b, uint16_t n ); uint8_t Rep[ 8 ]; -}; - -//----------------------------------------------------------------------------- -// compute_checksum -//----------------------------------------------------------------------------- -template - void compute_checksum( - IcmpHeader& header, - Iterator body_begin, - Iterator body_end ) - { - unsigned int sum = (header.get_type() << 8) + header.get_code() - + header.get_identifier() + header.get_sequence_number(); - - Iterator body_iter = body_begin; - while ( body_iter != body_end ) - { - sum += (static_cast ( *body_iter++ ) << 8); - if (body_iter != body_end) - sum += static_cast ( *body_iter++ ); - } - - sum = (sum >> 16) + (sum & 0xFFFF); - sum += (sum >> 16); - header.set_checksum( static_cast ( ~sum ) ); - } +}; #endif // ICMP_HEADER_H -- 1.7.1