From: Guilherme Maciel Ferreira Date: Sun, 6 Nov 2011 20:11:12 +0000 (-0200) Subject: Bring aboard TCP segment (IP and TCP headers) X-Git-Tag: v1.2~34 X-Git-Url: http://developer.intra2net.com/git/?a=commitdiff_plain;h=c2601cc966fa31c28573e53ea11351b45a98c0cd;p=pingcheck Bring aboard TCP segment (IP and TCP headers) - This allows to polymorphically change IPv4 and IPv6 --- diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index 089be10..c4bc227 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -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 index 0000000..8902676 --- /dev/null +++ b/src/tcp/tcpipv4segment.cpp @@ -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 + +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 index 0000000..09600a7 --- /dev/null +++ b/src/tcp/tcpipv4segment.h @@ -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 index 0000000..97839b1 --- /dev/null +++ b/src/tcp/tcpsegment.cpp @@ -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 index 0000000..1ad01ab --- /dev/null +++ b/src/tcp/tcpsegment.h @@ -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 + +#include +#include + +//----------------------------------------------------------------------------- +// 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 TcpSegmentItem; + +#endif // TCP_SEGMENT_H