Refactored the checksum calculation and IcmpHeader class
authorGuilherme Maciel Ferreira <guilherme.maciel.ferreira@intra2net.com>
Fri, 25 Feb 2011 10:56:32 +0000 (11:56 +0100)
committerGuilherme Maciel Ferreira <guilherme.maciel.ferreira@intra2net.com>
Fri, 25 Feb 2011 10:56:32 +0000 (11:56 +0100)
- 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
src/ping/checksumcalculator.h [new file with mode: 0644]
src/ping/icmpbody.h [new file with mode: 0644]
src/ping/icmpchecksumcalculator.h [new file with mode: 0644]
src/ping/icmpheader.h

index 605b43f..00497c9 100644 (file)
@@ -7,7 +7,9 @@
 #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"
 
@@ -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 (file)
index 0000000..9b5b657
--- /dev/null
@@ -0,0 +1,70 @@
+#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 */
diff --git a/src/ping/icmpbody.h b/src/ping/icmpbody.h
new file mode 100644 (file)
index 0000000..0878949
--- /dev/null
@@ -0,0 +1,12 @@
+#ifndef ICMPBODY_H
+#define ICMPBODY_H
+
+#include <string>
+
+//-----------------------------------------------------------------------------
+// IcmpBody
+//-----------------------------------------------------------------------------
+
+typedef std::string IcmpBody;
+
+#endif /* ICMPBODY_H */
diff --git a/src/ping/icmpchecksumcalculator.h b/src/ping/icmpchecksumcalculator.h
new file mode 100644 (file)
index 0000000..9d475bf
--- /dev/null
@@ -0,0 +1,13 @@
+#ifndef ICMPCHECKSUMCALCULATOR_H
+#define ICMPCHECKSUMCALCULATOR_H
+
+#include "checksumcalculator.h"
+#include "icmpbody.h"
+
+//-----------------------------------------------------------------------------
+// IcmpChecksumCalculator
+//-----------------------------------------------------------------------------
+
+typedef ChecksumCalculator<IcmpBody::iterator> IcmpChecksumCalculator;
+
+#endif /* ICMPCHECKSUMCALCULATOR_H */
index 7a7984f..61e1b0e 100644 (file)
@@ -1,7 +1,6 @@
 #ifndef ICMP_HEADER_HPP
 #define ICMP_HEADER_HPP
 
-#include <algorithm>
 #include <istream>
 #include <ostream>
 #include <stdint.h>
@@ -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<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