From: Guilherme Maciel Ferreira Date: Sat, 12 Nov 2011 19:38:22 +0000 (-0200) Subject: Bring aboard TCP header class for IPv6 X-Git-Tag: v1.2~20 X-Git-Url: http://developer.intra2net.com/git/?a=commitdiff_plain;h=bc4d0a3a5d4f8389f72009a2d69aea5f00734361;p=pingcheck Bring aboard TCP header class for IPv6 --- diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index c4d9941..d2edbde 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -39,6 +39,7 @@ set(SOURCES dns/timetolive.cpp host/hoststatusanalyzer.cpp host/messagepayload.cpp + host/networkinterfacelist.cpp host/pinger.cpp host/pingerfactory.cpp host/pinginterval.cpp @@ -63,6 +64,7 @@ set(SOURCES tcp/tcpheader.cpp tcp/tcppinger.cpp tcp/tcpipv4segment.cpp + tcp/tcpipv6segment.cpp tcp/tcpsegment.cpp tcp/tcpsegmentfactory.cpp main.cpp diff --git a/src/tcp/tcpipv6segment.cpp b/src/tcp/tcpipv6segment.cpp new file mode 100644 index 0000000..49593e6 --- /dev/null +++ b/src/tcp/tcpipv6segment.cpp @@ -0,0 +1,175 @@ +/* + 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/tcpipv6segment.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; + +//----------------------------------------------------------------------------- +// TcpIpv6Segment +//----------------------------------------------------------------------------- + +/** + * @brief Default constructor. + */ +TcpIpv6Segment::TcpIpv6Segment() : + IpHeader(), + TcpHdr() +{ +} + +/** + * @brief Parameterized constructor. + * + * @param tcp_header The TCP header. + */ +TcpIpv6Segment::TcpIpv6Segment( const TcpHeader &tcp_header ) : + IpHeader(), + TcpHdr( tcp_header ) +{ +} + +/** + * @brief Destructor. + */ +TcpIpv6Segment::~TcpIpv6Segment() +{ +} + +/** + * @brief Obtain the IP header. + * + * @return The IP header object. + */ +Ipv6Header TcpIpv6Segment::get_ip_header() const +{ + return IpHeader; +} + +/** + * @brief Obtain the TCP header. + * + * @return The TCP header object. + */ +TcpHeader TcpIpv6Segment::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 TcpIpv6Segment::match_rst_reply( + const address &source_address +) const +{ + Ipv6Header ipv6_header = get_ip_header(); + TcpHeader tcp_header = get_tcp_header(); + + bool match_reset = tcp_header.get_reset(); + bool match_address = ipv6_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 TcpIpv6Segment::print_rst_reply( + const ptime &time_segment_sent +) const +{ + Ipv6Header ipv6_header = get_ip_header(); + TcpHeader tcp_header = get_tcp_header(); + + ptime now = microsec_clock::universal_time(); + GlobalLogger.info() << "RST from " << ipv6_header.get_source_address() + << ": tcp_seq=" << tcp_header.get_sequence_number() + << ", ttl=" << ipv6_header.get_hop_limit() + << " time=" << (now - time_segment_sent).total_milliseconds() << " ms" + << endl; +} + +/** + * @brief Read the TCP Segment from the @c istream. + * + * @param is The input stream. + * + * @return @c true if the read was successful, or @c false if an error occured. + */ +bool TcpIpv6Segment::read( istream &is ) +{ + is.clear(); + + is >> *this; + + return is.fail(); +} + +/** + * @brief Write the TCP Segment to the @c ostream. + * + * @param os The output stream. + * + * @return @c true if the write was successful, or @c false if an error occured. + */ +bool TcpIpv6Segment::write( ostream &os ) const +{ + os.clear(); + + os << *this; + + return os.fail(); +} + +istream& operator>>( + istream &is, + TcpIpv6Segment &segment +) +{ + is >> segment.IpHeader >> segment.TcpHdr; + + return is; +} + +ostream& operator<<( + ostream& os, + const TcpIpv6Segment &segment +) +{ + os << segment.TcpHdr; + + return os; +} diff --git a/src/tcp/tcpipv6segment.h b/src/tcp/tcpipv6segment.h new file mode 100644 index 0000000..e6030a8 --- /dev/null +++ b/src/tcp/tcpipv6segment.h @@ -0,0 +1,134 @@ +/* + 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_IPV6_SEGMENT_H +#define TCP_IPV6_SEGMENT_H + +#include "ip/ipv6header.h" +#include "tcp/tcpheader.h" +#include "tcp/tcpsegment.h" + +//----------------------------------------------------------------------------- +// TcpIpv6Segment +//----------------------------------------------------------------------------- + +/** + * @brief This class represents the TCP segment over IP version 6. + * + * The TCP Segment over IPv6 Packet format is: + * + * @code + * 0 3 4 11 12 15 16 23 24 31 + * +-------+---------------+--------------------------------------+ --- + * | | | | ^ + * |version| traffic class | flow label | | + * | (6) | | | | + * +-------+---------------+-------+--------------+---------------+ | + * | | | | | + * | payload length | next header | hop limit | | + * | | | | | + * +---------------+---------------+--------------+---------------+ | + * | | | + * | | | + * | | | + * | | | + * | | | + * | source IPv6 address | IPv6 Header + * | | 40 bytes + * | | | + * | | | + * | | | + * | | | + * | | | + * +--------------------------------------------------------------+ | + * | | | + * | | | + * | | | + * | | | + * | | | + * | destination IPv6 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 TcpIpv6Segment : public TcpSegment +{ +public: + TcpIpv6Segment(); + TcpIpv6Segment( const TcpHeader &tcp_header ); + virtual ~TcpIpv6Segment(); + + Ipv6Header 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, + TcpIpv6Segment &segment + ); + friend std::ostream& operator<<( + std::ostream &os, + const TcpIpv6Segment &segment + ); + +private: + /// The IP header. + Ipv6Header IpHeader; + /// The TCP header. + TcpHeader TcpHdr; + +}; + +#endif // TCP_IPV6_SEGMENT_H