--- /dev/null
+/*
+ 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;
+}
+
+
 
--- /dev/null
+/*
+ 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
 
--- /dev/null
+/*
+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