Bring aboard ICMP packet factory.
authorGuilherme Maciel Ferreira <guilherme.maciel.ferreira@gmail.com>
Fri, 4 Nov 2011 02:51:50 +0000 (00:51 -0200)
committerGuilherme Maciel Ferreira <guilherme.maciel.ferreira@gmail.com>
Fri, 4 Nov 2011 02:51:50 +0000 (00:51 -0200)
- This class handles the packet creation for ICMPv4 and ICMPv6

src/CMakeLists.txt
src/icmp/icmppacketfactory.cpp [new file with mode: 0644]
src/icmp/icmppacketfactory.h [new file with mode: 0644]
src/icmp/icmpv4packet.cpp
src/icmp/icmpv6packet.cpp
src/ip/ipversion.h [new file with mode: 0644]

index 82d52d0..089be10 100644 (file)
@@ -49,9 +49,12 @@ set(SOURCES
     icmp/icmpechorequestmessage.cpp
     icmp/icmpgenericmessage.cpp
     icmp/icmpv4header.cpp
+    icmp/icmpv6header.cpp
     icmp/icmpmessage.cpp
     icmp/icmpv4packet.cpp
+    icmp/icmpv6packet.cpp
     icmp/icmppacket.cpp
+    icmp/icmppacketfactory.cpp
     icmp/icmppinger.cpp
     ip/ipv4header.cpp
     ip/ipv6header.cpp
diff --git a/src/icmp/icmppacketfactory.cpp b/src/icmp/icmppacketfactory.cpp
new file mode 100644 (file)
index 0000000..be9405c
--- /dev/null
@@ -0,0 +1,143 @@
+/*
+ The software in this package is distributed under the GNU General
+ Public License version 2 (with a special exception described below).
+
+ A copy of GNU General Public License (GPL) is included in this distribution,
+ in the file COPYING.GPL.
+
+ As a special exception, if other files instantiate templates or use macros
+ or inline functions from this file, or you compile this file and link it
+ with other works to produce a work based on this file, this file
+ does not by itself cause the resulting work to be covered
+ by the GNU General Public License.
+
+ However the source code for this file must still be made available
+ in accordance with section (3) of the GNU General Public License.
+
+ This exception does not invalidate any other reasons why a work based
+ on this file might be covered by the GNU General Public License.
+ */
+
+#include "icmp/icmppacketfactory.h"
+
+#include <boost/assert.hpp>
+
+#include <logfunc.hpp>
+
+#include "icmp/icmpchecksum.h"
+#include "icmp/icmpdata.h"
+#include "icmp/icmptype.h"
+#include "icmp/icmpv4header.h"
+#include "icmp/icmpv4packet.h"
+#include "icmp/icmpv6header.h"
+#include "icmp/icmpv6packet.h"
+
+using namespace std;
+using I2n::Logger::GlobalLogger;
+
+//-----------------------------------------------------------------------------
+// IcmpPacketFactory
+//-----------------------------------------------------------------------------
+
+IcmpPacketItem IcmpPacketFactory::create_icmp_packet(
+        const IpVersion version,
+        istream &is
+)
+{
+    BOOST_ASSERT( (IP_VERSION_4 == version) || (IP_VERSION_6 == version) );
+
+    IcmpPacketItem icmp_packet;
+
+    switch ( version )
+    {
+        case IP_VERSION_4:
+            icmp_packet.reset(new Icmpv4Packet());
+            break;
+        case IP_VERSION_6:
+            icmp_packet.reset(new Icmpv6Packet());
+            break;
+        default:
+            BOOST_ASSERT( !"Invalid ICMP Packet Type." );
+            break;
+    }
+
+    if ( !icmp_packet->read( is ) )
+    {
+        GlobalLogger.notice() << "Could not read ICMP packet." << endl;
+
+        IcmpPacketItem icmp_packet_empty;
+        icmp_packet = icmp_packet_empty;
+    }
+
+    return icmp_packet;
+}
+
+IcmpPacketItem IcmpPacketFactory::create_icmp_packet_echo_request(
+        const IpVersion version,
+        const uint16_t identifier,
+        const uint16_t sequence_number
+)
+{
+    BOOST_ASSERT( (IP_VERSION_4 == version) || (IP_VERSION_6 == version) );
+
+    IcmpPacketItem icmp_packet;
+
+    switch (version)
+    {
+        case IP_VERSION_4:
+            icmp_packet = create_icmpv4_packet_echo_request( identifier, sequence_number );
+            break;
+        case IP_VERSION_6:
+            icmp_packet = create_icmpv6_packet_echo_request( identifier, sequence_number );
+            break;
+        default:
+            BOOST_ASSERT( !"Invalid ICMP Packet Type." );
+            break;
+    }
+
+    return icmp_packet;
+}
+
+IcmpPacketItem IcmpPacketFactory::create_icmpv4_packet_echo_request(
+        const uint16_t identifier,
+        const uint16_t sequence_number
+)
+{
+    const IcmpData icmp_data( "ping-message" );
+
+    Icmpv4Type type = Icmpv4Type_EchoRequest;
+    uint8_t code = 0;
+    IcmpChecksum calculator( icmp_data.begin(), icmp_data.end() );
+    uint16_t checksum = calculator.compute(
+            type, code, identifier, sequence_number
+    );
+    Icmpv4Header icmp_header(
+            type, code, checksum, identifier, sequence_number
+    );
+    IcmpPacketItem icmp_packet(new Icmpv4Packet( icmp_header, icmp_data ));
+
+    return icmp_packet;
+}
+
+IcmpPacketItem IcmpPacketFactory::create_icmpv6_packet_echo_request(
+        const uint16_t identifier,
+        const uint16_t sequence_number
+)
+{
+    const IcmpData icmp_data( "ping-message" );
+
+    Icmpv6Type type = Icmpv6Type_EchoRequest;
+    uint8_t code = 0;
+    IcmpChecksum calculator( icmp_data.begin(), icmp_data.end() );
+    uint16_t checksum = calculator.compute(
+            type, code, identifier, sequence_number
+    );
+    Icmpv6Header icmp_header(
+            type, code, checksum, identifier, sequence_number
+    );
+    IcmpPacketItem icmp_packet(new Icmpv6Packet( icmp_header, icmp_data ));
+
+    return icmp_packet;
+}
+
+
diff --git a/src/icmp/icmppacketfactory.h b/src/icmp/icmppacketfactory.h
new file mode 100644 (file)
index 0000000..2d774ee
--- /dev/null
@@ -0,0 +1,64 @@
+/*
+ The software in this package is distributed under the GNU General
+ Public License version 2 (with a special exception described below).
+
+ A copy of GNU General Public License (GPL) is included in this distribution,
+ in the file COPYING.GPL.
+
+ As a special exception, if other files instantiate templates or use macros
+ or inline functions from this file, or you compile this file and link it
+ with other works to produce a work based on this file, this file
+ does not by itself cause the resulting work to be covered
+ by the GNU General Public License.
+
+ However the source code for this file must still be made available
+ in accordance with section (3) of the GNU General Public License.
+
+ This exception does not invalidate any other reasons why a work based
+ on this file might be covered by the GNU General Public License.
+ */
+
+#ifndef ICMP_PACKET_FACTORY_H
+#define ICMP_PACKET_FACTORY_H
+
+#include <stdint.h>
+
+#include <iostream>
+
+#include "icmp/icmppacket.h"
+#include "ip/ipversion.h"
+
+//-----------------------------------------------------------------------------
+// IcmpPacketFactory
+//-----------------------------------------------------------------------------
+
+/**
+ * @brief Class which constructs ICMP Packets, hiding from the class users the
+ * underlying details on how to build each packet.
+ */
+class IcmpPacketFactory
+{
+public:
+    static IcmpPacketItem create_icmp_packet(
+            const IpVersion version,
+            std::istream &is
+    );
+    static IcmpPacketItem create_icmp_packet_echo_request(
+            const IpVersion type,
+            const uint16_t identifier,
+            const uint16_t sequence_number
+    );
+
+private:
+    static IcmpPacketItem create_icmpv4_packet_echo_request(
+            const uint16_t identifier,
+            const uint16_t sequence_number
+    );
+    static IcmpPacketItem create_icmpv6_packet_echo_request(
+            const uint16_t identifier,
+            const uint16_t sequence_number
+    );
+
+};
+
+#endif // ICMP_PACKET_FACTORY_H
index 0a60aa8..180d464 100644 (file)
@@ -204,6 +204,8 @@ void Icmpv4Packet::print_destination_unreachable() const
 
 bool Icmpv4Packet::read( istream &is )
 {
+    is.clear();
+
     is >> *this;
 
     return is.fail();
index ecaff54..1823d31 100644 (file)
@@ -204,6 +204,8 @@ void Icmpv6Packet::print_destination_unreachable() const
 
 bool Icmpv6Packet::read( istream &is )
 {
+    is.clear();
+
     is >> *this;
 
     return is.fail();
diff --git a/src/ip/ipversion.h b/src/ip/ipversion.h
new file mode 100644 (file)
index 0000000..feab94b
--- /dev/null
@@ -0,0 +1,30 @@
+/*
+The software in this package is distributed under the GNU General
+Public License version 2 (with a special exception described below).
+
+A copy of GNU General Public License (GPL) is included in this distribution,
+in the file COPYING.GPL.
+
+As a special exception, if other files instantiate templates or use macros
+or inline functions from this file, or you compile this file and link it
+with other works to produce a work based on this file, this file
+does not by itself cause the resulting work to be covered
+by the GNU General Public License.
+
+However the source code for this file must still be made available
+in accordance with section (3) of the GNU General Public License.
+
+This exception does not invalidate any other reasons why a work based
+on this file might be covered by the GNU General Public License.
+*/
+
+#ifndef IP_VERSION_H
+#define IP_VERSION_H
+
+enum IpVersion
+{
+    IP_VERSION_4,
+    IP_VERSION_6
+};
+
+#endif // IP_VERSION_H