#include <logfunc.hpp>
+#include "ip/ipversion.h"
+#include "tcp/tcpsegmentfactory.h"
+
using namespace std;
using boost::asio::const_buffers_1;
using boost::asio::io_service;
++SequenceNumber;
// Create an TCP header for an ACK request.
- uint16_t source_port = get_source_address();
- uint16_t destination_port = get_destination_port();
- TcpHeader tcp_header = create_ack_request(
- source_port,
- destination_port,
- ++SequenceNumber
- );
-
uint32_t source_address = get_source_address();
uint32_t destination_address = get_destination_address();
+ uint16_t source_port = get_source_port();
+ uint16_t destination_port = get_destination_port();
+ TcpSegmentItem tcp_segment = TcpSegmentFactory::create_tcp_segment_ack_request(
+ IP_VERSION_4, source_address, destination_address,
+ source_port, destination_port, SequenceNumber );
- uint16_t cksum = tcp_header.calculate_tcp_checksum(
- source_address, destination_address, NULL, 0
- );
- tcp_header.set_checksum( cksum );
-
- send_ack_request( tcp_header );
-}
-
-TcpHeader TcpPinger::create_ack_request(
- const uint16_t source_port,
- const uint16_t destination_port,
- const uint16_t sequence_number
-) const
-{
- // (5 words of 32 bits = 5 * 4 bytes = 20 bytes)
- const uint8_t header_size_in_words = 5; // size in units of 32 bits
- const uint16_t window_size_in_octets = 32768;
-
- // Create an TCP header for an ACK request.
- TcpHeader tcp_header;
- tcp_header.set_source_port( source_port ); // assign a random ephemeral port number
- tcp_header.set_destination_port( destination_port );
- tcp_header.set_sequence_number( sequence_number );
- tcp_header.set_header_length( header_size_in_words );
- tcp_header.set_acknowledgment( true );
- tcp_header.set_window_size( window_size_in_octets ); // window size
-
- return tcp_header;
+ send_ack_request( tcp_segment );
}
-void TcpPinger::send_ack_request( const TcpHeader &tcp_header )
+void TcpPinger::send_ack_request( const TcpSegmentItem tcp_segment )
{
// Encode the request packet.
boost::asio::streambuf request_buffer;
ostream os( &request_buffer );
- os << tcp_header;
+ tcp_segment->write( os );
TimeSent = microsec_clock::universal_time();
return;
}
- Ipv4Header ipv4_header;
- TcpHeader tcp_header;
- is >> ipv4_header >> tcp_header;
+ // Decode the reply segment.
+ TcpSegmentItem tcp_segment = TcpSegmentFactory::create_tcp_segment( IP_VERSION_4, is );
- // filter out only the TCP reset (RST) replies. Note that the sequence
+ // Filter out only the TCP reset (RST) replies. Note that the sequence
// number from RST does not match the sent ACK's sequence number.
- if ( tcp_header.get_reset() &&
- ipv4_header.get_source_address() == DestinationEndpoint.address() )
+ if ( tcp_segment->match_rst_reply( DestinationEndpoint.address() ) )
{
ReceivedReply = true;
- print_rst_reply( ipv4_header, tcp_header );
+ tcp_segment->print_rst_reply( TimeSent );
set_ping_status( PingStatus_SuccessReply );
}
}
-/**
- * @brief Prints the RST reply.
- *
- * @param ipv4_header The IPv4 header received.
- * @param tcp_header The TCP RST header.
- * @return void
- */
-void TcpPinger::print_rst_reply(
- const Ipv4Header &ipv4_header,
- const TcpHeader &tcp_header
-) const
-{
- 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 - TimeSent).total_milliseconds() << " ms" << endl;
-}
-
-
void TcpPinger::set_ping_status( PingStatus ping_status )
{
PingerStatus = ping_status;
#include "host/networkinterface.hpp"
#include "host/pinger.h"
#include "host/pingstatus.h"
-#include "ip/ipv4header.h"
-#include "tcp/tcpheader.h"
+#include "tcp/tcpsegment.h"
//-----------------------------------------------------------------------------
// TcpPinger
);
void start_send();
- TcpHeader create_ack_request(
- const uint16_t source_port,
- const uint16_t destination_port,
- const uint16_t sequence_number
- ) const;
- void send_ack_request( const TcpHeader &tcp_header );
+ void send_ack_request( const TcpSegmentItem tcp_segment );
void schedule_timeout_rst_reply();
void handle_ping_done();
void start_receive();
void handle_receive_tcp_segment( const std::size_t &bytes_transferred );
- void print_rst_reply(
- const Ipv4Header &ipv4_header,
- const TcpHeader &tcp_header
- ) const;
-
void set_ping_status( PingStatus ping_status );
private:
/// the buffer where the data received will be placed
boost::asio::streambuf ReplyBuffer;
/// flag to indicate if we got a reply or not
- /// number of replies to the ICMP echo request
bool ReceivedReply;
/// the amount of time to wait for the reply
int RstReplyTimeoutInSec;