#include <sys/socket.h>
#include <sys/types.h>
-#include "icmp_header.h"
+#include "icmpbody.h"
+#include "icmpchecksumcalculator.h"
+#include "icmpheader.h"
#include "ipv4_header.h"
#include "boostpinger.h"
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;
--- /dev/null
+#ifndef CHECKSUMCALCULATOR_H
+#define CHECKSUMCALCULATOR_H
+
+#include <stdint.h>
+
+//-----------------------------------------------------------------------------
+// ChecksumCalculator
+//-----------------------------------------------------------------------------
+
+template<typename Iterator>
+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<typename Iterator>
+ ChecksumCalculator<Iterator>::ChecksumCalculator(
+ Iterator body_begin,
+ Iterator body_end
+ ) :
+ body_begin(),
+ body_end()
+ {
+ this->body_begin = body_begin;
+ this->body_end = body_end;
+ }
+
+template<typename Iterator>
+ uint16_t ChecksumCalculator<Iterator>::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<uint8_t> ( *body_iter++ ) << 8);
+ if ( body_iter != body_end )
+ sum += static_cast<uint8_t> ( *body_iter++ );
+ }
+
+ sum = (sum >> 16) + (sum & 0xFFFF);
+ sum += (sum >> 16);
+
+ uint16_t checksum = static_cast<uint16_t> ( ~sum );
+
+ return checksum;
+ }
+
+#endif /* CHECKSUMCALCULATOR_H */
--- /dev/null
+#ifndef ICMPBODY_H
+#define ICMPBODY_H
+
+#include <string>
+
+//-----------------------------------------------------------------------------
+// IcmpBody
+//-----------------------------------------------------------------------------
+
+typedef std::string IcmpBody;
+
+#endif /* ICMPBODY_H */
--- /dev/null
+#ifndef ICMPCHECKSUMCALCULATOR_H
+#define ICMPCHECKSUMCALCULATOR_H
+
+#include "checksumcalculator.h"
+#include "icmpbody.h"
+
+//-----------------------------------------------------------------------------
+// IcmpChecksumCalculator
+//-----------------------------------------------------------------------------
+
+typedef ChecksumCalculator<IcmpBody::iterator> IcmpChecksumCalculator;
+
+#endif /* ICMPCHECKSUMCALCULATOR_H */
#ifndef ICMP_HEADER_HPP
#define ICMP_HEADER_HPP
-#include <algorithm>
#include <istream>
#include <ostream>
#include <stdint.h>
IcmpHeader(
IcmpType type,
uint8_t code,
+ uint16_t checksum,
uint16_t identifier,
uint16_t sequence_number
);
void encode( int a, int b, uint16_t n );
uint8_t Rep[ 8 ];
-};
-
-//-----------------------------------------------------------------------------
-// compute_checksum
-//-----------------------------------------------------------------------------
-template<typename Iterator>
- 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<uint8_t> ( *body_iter++ ) << 8);
- if (body_iter != body_end)
- sum += static_cast<uint8_t> ( *body_iter++ );
- }
-
- sum = (sum >> 16) + (sum & 0xFFFF);
- sum += (sum >> 16);
- header.set_checksum( static_cast<uint16_t> ( ~sum ) );
- }
+};
#endif // ICMP_HEADER_H