Bring aboard TCP segment (IP and TCP headers)
authorGuilherme Maciel Ferreira <guilherme.maciel.ferreira@gmail.com>
Sun, 6 Nov 2011 20:11:12 +0000 (18:11 -0200)
committerGuilherme Maciel Ferreira <guilherme.maciel.ferreira@gmail.com>
Sun, 6 Nov 2011 20:11:12 +0000 (18:11 -0200)
- This allows to polymorphically change IPv4 and IPv6

src/CMakeLists.txt
src/tcp/tcpipv4segment.cpp [new file with mode: 0644]
src/tcp/tcpipv4segment.h [new file with mode: 0644]
src/tcp/tcpsegment.cpp [new file with mode: 0644]
src/tcp/tcpsegment.h [new file with mode: 0644]

index 089be10..c4bc227 100644 (file)
@@ -62,6 +62,8 @@ set(SOURCES
     link/statusnotifiercommand.cpp
     tcp/tcpheader.cpp
     tcp/tcppinger.cpp
+    tcp/tcpipv4segment.cpp
+    tcp/tcpsegment.cpp
     main.cpp
 )
 
diff --git a/src/tcp/tcpipv4segment.cpp b/src/tcp/tcpipv4segment.cpp
new file mode 100644 (file)
index 0000000..8902676
--- /dev/null
@@ -0,0 +1,161 @@
+/*
+ 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 "tcp/tcpipv4segment.h"
+
+#include <logfunc.hpp>
+
+using namespace std;
+using boost::asio::ip::address;
+using boost::posix_time::ptime;
+using boost::posix_time::microsec_clock;
+using I2n::Logger::GlobalLogger;
+
+//-----------------------------------------------------------------------------
+// TcpIpv4Segment
+//-----------------------------------------------------------------------------
+
+/**
+ * @brief Default constructor.
+ */
+TcpIpv4Segment::TcpIpv4Segment() :
+    IpHeader(),
+    TcpHdr()
+{
+}
+
+/**
+ * @brief Parameterized constructor.
+ *
+ * @param tcp_header The TCP header.
+ */
+TcpIpv4Segment::TcpIpv4Segment( const TcpHeader &tcp_header ) :
+    IpHeader(),
+    TcpHdr( tcp_header )
+{
+}
+
+/**
+ * @brief Destructor.
+ */
+TcpIpv4Segment::~TcpIpv4Segment()
+{
+}
+
+/**
+ * @brief Obtain the IP header.
+ *
+ * @return The IP header object.
+ */
+Ipv4Header TcpIpv4Segment::get_ip_header() const
+{
+    return IpHeader;
+}
+
+/**
+ * @brief Obtain the TCP header.
+ *
+ * @return The TCP header object.
+ */
+TcpHeader TcpIpv4Segment::get_tcp_header() const
+{
+    return TcpHdr;
+}
+
+/**
+ * @brief Convenience method to check if this segment, matching the arguments,
+ * is a RST reply.
+ *
+ * @param source_address The source address.
+ *
+ * @return @c true if this packet is a RST reply, or @c false otherwise.
+ */
+bool TcpIpv4Segment::match_rst_reply(
+        const address &source_address
+) const
+{
+    Ipv4Header ipv4_header = get_ip_header();
+    TcpHeader tcp_header = get_tcp_header();
+
+    bool match_reset = tcp_header.get_reset();
+    bool match_address = ipv4_header.get_source_address() == source_address;
+
+    return ( match_reset && match_address );
+}
+
+/**
+ * @brief Prints the RST reply.
+ *
+ * @param time_segment_sent The time when this segment was sent.
+ *
+ * @return void
+ */
+void TcpIpv4Segment::print_rst_reply(
+        const ptime &time_segment_sent
+) const
+{
+    Ipv4Header ipv4_header = get_ip_header();
+    TcpHeader tcp_header = get_tcp_header();
+
+    ptime now = microsec_clock::universal_time();
+    GlobalLogger.info() << "RST from " << ipv4_header.get_source_address()
+        << ": tcp_seq=" << tcp_header.get_sequence_number()
+        << ", ttl=" << ipv4_header.get_time_to_live()
+        << " time=" << (now - time_segment_sent).total_milliseconds() << " ms"
+        << endl;
+}
+
+bool TcpIpv4Segment::read( std::istream &is )
+{
+    is.clear();
+
+    is >> *this;
+
+    return is.fail();
+}
+
+bool TcpIpv4Segment::write( std::ostream &os ) const
+{
+    os.clear();
+
+    os << *this;
+
+    return os.fail();
+}
+
+istream& operator>>(
+        istream &is,
+        TcpIpv4Segment &segment
+)
+{
+    is >> segment.IpHeader >> segment.TcpHdr;
+
+    return is;
+}
+
+ostream& operator<<(
+        ostream& os,
+        const TcpIpv4Segment &segment
+)
+{
+    os << segment.TcpHdr;
+
+    return os;
+}
diff --git a/src/tcp/tcpipv4segment.h b/src/tcp/tcpipv4segment.h
new file mode 100644 (file)
index 0000000..09600a7
--- /dev/null
@@ -0,0 +1,120 @@
+/*
+ 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 TCP_IPV4_SEGMENT_H
+#define TCP_IPV4_SEGMENT_H
+
+#include "ip/ipv4header.h"
+#include "tcp/tcpheader.h"
+#include "tcp/tcpsegment.h"
+
+//-----------------------------------------------------------------------------
+// TcpIpv4Segment
+//-----------------------------------------------------------------------------
+
+/**
+ * @brief This class represents the TCP segment over IP version 4.
+ *
+ * The TCP Segment over IPv4 Packet format is:
+ *
+ * @code
+ * 0               8               16                             31
+ * +-------+-------+---------------+------------------------------+      ---
+ * |       |       |               |                              |       ^
+ * |version|header |    type of    |    total length in bytes     |       |
+ * |  (4)  | length|    service    |                              |       |
+ * +-------+-------+---------------+-+-+-+------------------------+       |
+ * |                               | | | |                        |       |
+ * |        identification         |0|D|M|    fragment offset     |       |
+ * |                               | |F|F|                        |       |
+ * +---------------+---------------+-+-+-+------------------------+       |
+ * |               |               |                              |       |
+ * | time to live  |   protocol    |       header checksum        |  IPv4 Header
+ * |               |               |                              |   20 bytes
+ * +---------------+---------------+------------------------------+       |
+ * |                                                              |       |
+ * |                      source IPv4 address                     |       |
+ * |                                                              |       |
+ * +--------------------------------------------------------------+       |
+ * |                                                              |       |
+ * |                   destination IPv4 address                   |       |
+ * |                                                              |       v
+ * +-------------------------------+------------------------------+      ---
+ * |                               |                              |       ^
+ * |         source port           |     destination port         |       |
+ * |                               |                              |       |
+ * +--------------------------------------------------------------+       |
+ * |                                                              |       |
+ * |                        sequence number                       |       |
+ * |                                                              |       |
+ * +--------------------------------------------------------------+       |
+ * |                                                              |  TCP Header
+ * |              acknowledgment number (if ACK set)              |   20 bytes
+ * |                                                              |       |
+ * +-------+-------+-+-+-+-+-+-+-+-+------------------------------+       |
+ * | data  | reser-|C|E|U|A|P|R|S|F|                              |       |
+ * |offset | ved   |W|C|R|C|S|S|Y|I|        window size           |       |
+ * |       |       |R|E|G|K|H|T|N|N|                              |       |
+ * +---------------+-+-+-+-+-+-+-+-+------------------------------+       |
+ * |                               |                              |       |
+ * |          checksum             | urgent pointer (if URG set)  |       |
+ * |                               |                              |       v
+ * +-----------------------------------------------+--------------+      ---
+ * @endcode
+ */
+class TcpIpv4Segment : public TcpSegment
+{
+public:
+    TcpIpv4Segment();
+    TcpIpv4Segment( const TcpHeader &tcp_header );
+    virtual ~TcpIpv4Segment();
+
+    Ipv4Header get_ip_header() const;
+    TcpHeader get_tcp_header() const;
+
+    virtual bool match_rst_reply(
+            const boost::asio::ip::address &source_address
+    ) const;
+
+    virtual void print_rst_reply(
+            const boost::posix_time::ptime &time_segment_sent
+    ) const;
+
+    virtual bool read( std::istream &is );
+    virtual bool write( std::ostream &os ) const;
+
+    friend std::istream& operator>>(
+            std::istream &is,
+            TcpIpv4Segment &segment
+    );
+    friend std::ostream& operator<<(
+            std::ostream &os,
+            const TcpIpv4Segment &segment
+    );
+
+private:
+    /// The IP header.
+    Ipv4Header IpHeader;
+    /// The TCP header.
+    TcpHeader TcpHdr;
+
+};
+
+#endif // TCP_IPV4_SEGMENT_H
diff --git a/src/tcp/tcpsegment.cpp b/src/tcp/tcpsegment.cpp
new file mode 100644 (file)
index 0000000..97839b1
--- /dev/null
@@ -0,0 +1,55 @@
+/*
+ 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 "tcp/tcpsegment.h"
+
+//-----------------------------------------------------------------------------
+// TcpSegment
+//-----------------------------------------------------------------------------
+
+/**
+ * @brief Default constructor.
+ */
+TcpSegment::TcpSegment()
+{
+}
+
+/**
+ * @brief Copy constructor.
+ */
+TcpSegment::TcpSegment( const TcpSegment & )
+{
+}
+
+/**
+ * @brief Destructor.
+ */
+TcpSegment::~TcpSegment()
+{
+}
+
+/**
+ * @brief Copy assignment operator.
+ */
+TcpSegment& TcpSegment::operator=( const TcpSegment & )
+{
+    return *this;
+}
+
diff --git a/src/tcp/tcpsegment.h b/src/tcp/tcpsegment.h
new file mode 100644 (file)
index 0000000..1ad01ab
--- /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 TCP_SEGMENT_H
+#define TCP_SEGMENT_H
+
+#include <iostream>
+
+#include <boost/asio.hpp>
+#include <boost/shared_ptr.hpp>
+
+//-----------------------------------------------------------------------------
+// TcpSegment
+//-----------------------------------------------------------------------------
+
+/**
+ * @brief Abstract class for TCP Segments.
+ */
+class TcpSegment
+{
+public:
+    virtual bool match_rst_reply(
+            const boost::asio::ip::address &source_address
+    ) const = 0;
+
+    virtual void print_rst_reply(
+            const boost::posix_time::ptime &time_packet_sent
+    ) const = 0;
+
+    virtual bool read( std::istream &is ) = 0;
+    virtual bool write( std::ostream &os ) const = 0;
+
+protected:
+    TcpSegment();
+    TcpSegment( const TcpSegment &other );
+    virtual ~TcpSegment();
+
+    TcpSegment& operator=( const TcpSegment &other );
+};
+
+//-----------------------------------------------------------------------------
+// TcpSegmentItem
+//-----------------------------------------------------------------------------
+
+typedef boost::shared_ptr<TcpSegment> TcpSegmentItem;
+
+#endif // TCP_SEGMENT_H