.cproject
.project
.directory
+
+# uml cache files
+*.vpp~*
+# project definitions
+project( libpingcheck CXX )
+set( VERSION 0.0.1 )
cmake_minimum_required( VERSION 2.6 )
-project( pinger CXX )
-
# set the directory where the executable will be placed
set( CMAKE_RUNTIME_OUTPUT_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR} )
# set the directory where the make install places the executable
#set( CMAKE_INSTALL_PREFIX ${CMAKE_CURRENT_BINARY_DIR} )
+# more build in the source folder
add_subdirectory( src )
-set( SOURCES
- icmp_header.cpp
- ipv4_header.cpp
- pinger.cpp
- main.cpp
-)
-
-set( TARGET pinger )
+# binary name
+set( TARGET pingcheck )
+# required boost libraries
set( Boost_USE_STATIC_LIBS ON )
set( Boost_USE_MULTITHREADED ON )
set( Boost_USE_STATIC_RUNTIME OFF )
find_package( Boost 1.36.0 REQUIRED COMPONENTS filesystem )
+include_directories( config )
+include_directories( ping )
include_directories( ${Boost_INCLUDE_DIRS} )
+
+set( SOURCES
+ config/configuration.cpp
+ config/configurationcommandline.cpp
+ config/configurationfile.cpp
+ config/configurationreader.cpp
+ ping/boostpinger.cpp
+ ping/host.cpp
+ ping/icmp_header.cpp
+ ping/ipv4_header.cpp
+ ping/pingcheck.cpp
+ ping/pinger.cpp
+ ping/pingmanager.cpp
+ main.cpp
+)
+
+# creates the binary
add_executable( ${TARGET} ${SOURCES} )
+
+# link the program against the libraries
target_link_libraries( ${TARGET} ${Boost_LIBRARIES} )
-install(
- TARGETS ${TARGET}
- DESTINATION .
-)
\ No newline at end of file
+# creates the install rule for the binary
+install( TARGETS ${TARGET} DESTINATION . )
--- /dev/null
+#include "configuration.h"
+
+Configuration::Configuration()
+{
+}
+
+Configuration::~Configuration()
+{
+}
--- /dev/null
+#ifndef CONFIGURATION_H_
+#define CONFIGURATION_H_
+
+#include <string>
+#include <vector>
+#include <stdint.h>
+
+#include "host.h"
+
+class Configuration
+{
+public:
+ Configuration();
+ virtual ~Configuration();
+
+ virtual void read() = 0;
+
+private:
+ std::string call_fail_command;
+ std::string logfile;
+ bool daemonize;
+ uint32_t limit_down_hosts_to_notify;
+ std::vector<Host> hosts;
+
+};
+
+#endif /* CONFIGURATION_H_ */
--- /dev/null
+#include "configurationcommandline.h"
+
+ConfigurationCommandLine::ConfigurationCommandLine()
+{
+}
+
+ConfigurationCommandLine::~ConfigurationCommandLine()
+{
+}
+
+void ConfigurationCommandLine::read()
+{
+
+}
--- /dev/null
+#ifndef CONFIGURATIONCOMMANDLINE_H_
+#define CONFIGURATIONCOMMANDLINE_H_
+
+#include "configuration.h"
+
+class ConfigurationCommandLine : public Configuration
+{
+public:
+ ConfigurationCommandLine();
+ virtual ~ConfigurationCommandLine();
+
+ void read();
+
+};
+
+#endif /* CONFIGURATIONCOMMANDLINE_H_ */
--- /dev/null
+#include "configurationfile.h"
+
+ConfigurationFile::ConfigurationFile()
+{
+}
+
+ConfigurationFile::~ConfigurationFile()
+{
+}
+
+void ConfigurationFile::read()
+{
+
+}
--- /dev/null
+#ifndef CONFIGURATIONFILE_H_
+#define CONFIGURATIONFILE_H_
+
+#include "configuration.h"
+
+class ConfigurationFile : public Configuration
+{
+public:
+ ConfigurationFile();
+ virtual ~ConfigurationFile();
+
+ void read();
+};
+
+#endif /* CONFIGURATIONFILE_H_ */
--- /dev/null
+#include "configurationreader.h"
+
+ConfigurationReader::ConfigurationReader()
+{
+ // TODO how to select the source? Shall the main pass the command line?
+}
+
+ConfigurationReader::~ConfigurationReader()
+{
+}
+
+void ConfigurationReader::read()
+{
+ // if user provides parameters to command line
+ // parse and use the parameters
+ // configuration = new ConfigurationCommandLine
+ // if user provides a file path to command line
+ // read the given configuration file
+ // configuration = new ConfigurationFile( file from command line )
+ // if user doesn't provide any file or parameters
+ // read the default file at the default location
+ // configuration = new ConfigurationFile( default file )
+ //
+ // configuration->read();
+}
+
+Configuration *ConfigurationReader::getConfiguration() const
+{
+ return configuration;
+}
+
--- /dev/null
+#ifndef CONFIGURATIONREADER_H_
+#define CONFIGURATIONREADER_H_
+
+#include "configuration.h"
+
+class ConfigurationReader
+{
+public:
+ ConfigurationReader();
+ virtual ~ConfigurationReader();
+
+ void read();
+ Configuration *getConfiguration() const;
+
+private:
+ Configuration *configuration;
+};
+
+#endif /* CONFIGURATIONREADER_H_ */
+#include <boost/asio.hpp>
+#include <boost/bind.hpp>
+#include <istream>
#include <iostream>
+#include <ostream>
-#include "pinger.hpp"
+#include "host.h"
+#include "boostpinger.h"
int main( int argc, char* argv[] )
{
- try
+ if (argc != 2)
{
- if (argc != 2)
- {
- std::cerr << "Usage: ping <host>" << std::endl;
- std::cerr << "(You may need to run this program as root.)"
- << std::endl;
- return 1;
- }
+ std::cerr << "Usage: ping <host>" << std::endl;
+ std::cerr << "(You may need to run this program as root.)" << std::endl;
+ return 1;
+ }
+ try
+ {
boost::asio::io_service io_service;
- Pinger p( io_service, argv[ 1 ] );
+ BoostPinger p( io_service );
+ Host host( argv[ 1 ] );
+ p.ping( host );
io_service.run();
}
catch (std::exception& e)
#include <sys/socket.h>
#include <sys/types.h>
-#include "icmp_header.hpp"
-#include "ipv4_header.hpp"
-#include "pinger.hpp"
+#include "icmp_header.h"
+#include "ipv4_header.h"
+#include "boostpinger.h"
//-----------------------------------------------------------------------------
-// Pinger
+// BoostPinger
//-----------------------------------------------------------------------------
-Pinger::Pinger( boost::asio::io_service& io_service, const char* destination ) :
- m_resolver( io_service ), m_timer( io_service ), m_sequence_number( 0 ),
- m_num_replies( 0 ), m_socket( io_service, icmp::v4() )
+BoostPinger::BoostPinger(
+ boost::asio::io_service& io_service
+) :
+ resolver( io_service ), timer( io_service ), sequence_number( 0 ),
+ num_replies( 0 ), socket( io_service, icmp::v4() )
{
+#if 0
try
{
std::string ip = "172.16.1.149";
uint32_t port = 21;
icmp::endpoint ep( address::from_string( ip ), port );
- m_socket.bind( ep );
+ socket.bind( ep );
}
catch (boost::system::system_error &e)
{
std::cerr << "exception" << std::endl;
}
+#endif
+}
+
+BoostPinger::~BoostPinger()
+{
+}
+
+void BoostPinger::ping( const Host &host )
+{
+ std::string destination = host.getIp();
+ // TODO what if it is an DNS?
icmp::resolver::query query( icmp::v4(), destination, "" );
- m_destination = *m_resolver.resolve( query );
+ destination_endpoint = *resolver.resolve( query );
start_send();
start_receive();
}
-Pinger::~Pinger()
-{
-}
-
-void Pinger::start_send()
+void BoostPinger::start_send()
{
std::string body( "ping message" );
echo_request.type( IcmpHeader::EchoRequest );
echo_request.code( 0 );
echo_request.identifier( get_identifier() );
- m_sequence_number++;
- echo_request.sequence_number( m_sequence_number );
+ sequence_number++;
+ echo_request.sequence_number( sequence_number );
compute_checksum( echo_request, body.begin(), body.end() );
// Encode the request packet.
os << echo_request << body;
// Send the request.
- m_time_sent = posix_time::microsec_clock::universal_time();
- m_socket.send_to( request_buffer.data(), m_destination );
+ time_sent = posix_time::microsec_clock::universal_time();
+ socket.send_to( request_buffer.data(), destination_endpoint );
// Wait up to five seconds for a reply.
- m_num_replies = 0;
- m_timer.expires_at( m_time_sent + posix_time::seconds( 5 ) );
- m_timer.async_wait( boost::bind( &Pinger::handle_timeout, this ) );
+ num_replies = 0;
+ timer.expires_at( time_sent + posix_time::seconds( 5 ) );
+ timer.async_wait( boost::bind( &BoostPinger::handle_timeout, this ) );
}
-void Pinger::handle_timeout()
+void BoostPinger::handle_timeout()
{
- if (m_num_replies == 0)
+ if (num_replies == 0)
std::cout << "Request timed out" << std::endl;
// Requests must be sent no less than one second apart.
- m_timer.expires_at( m_time_sent + posix_time::seconds( 1 ) );
- m_timer.async_wait( boost::bind( &Pinger::start_send, this ) );
+ timer.expires_at( time_sent + posix_time::seconds( 1 ) );
+ timer.async_wait( boost::bind( &BoostPinger::start_send, this ) );
}
-void Pinger::start_receive()
+void BoostPinger::start_receive()
{
// Discard any data already in the buffer.
- m_reply_buffer.consume( m_reply_buffer.size() );
+ reply_buffer.consume( reply_buffer.size() );
// Wait for a reply. We prepare the buffer to receive up to 64KB.
- m_socket.async_receive(
- m_reply_buffer.prepare( 65536 ),
- boost::bind( &Pinger::handle_receive, this, _2 ) );
+ socket.async_receive(
+ reply_buffer.prepare( 65536 ),
+ boost::bind( &BoostPinger::handle_receive, this, _2 ) );
}
-void Pinger::handle_receive( std::size_t length )
+void BoostPinger::handle_receive( std::size_t length )
{
// The actual number of bytes received is committed to the buffer so that we
// can extract it using a std::istream object.
- m_reply_buffer.commit( length );
+ reply_buffer.commit( length );
// Decode the reply packet.
- std::istream is( &m_reply_buffer );
+ std::istream is( &reply_buffer );
Ipv4Header ipv4_hdr;
IcmpHeader icmp_hdr;
is >> ipv4_hdr >> icmp_hdr;
// expected sequence number.
if (is && icmp_hdr.type() == IcmpHeader::EchoReply
&& icmp_hdr.identifier() == get_identifier()
- && icmp_hdr.sequence_number() == m_sequence_number)
+ && icmp_hdr.sequence_number() == sequence_number)
{
// If this is the first reply, interrupt the five second timeout.
- if (m_num_replies++ == 0)
- m_timer.cancel();
+ if (num_replies++ == 0)
+ timer.cancel();
// Print out some information about the reply packet.
posix_time::ptime now = posix_time::microsec_clock::universal_time();
<< ipv4_hdr.source_address() << ": icmp_seq="
<< icmp_hdr.sequence_number() << ", ttl="
<< ipv4_hdr.time_to_live() << ", time="
- << (now - m_time_sent).total_milliseconds() << " ms"
+ << (now - time_sent).total_milliseconds() << " ms"
<< std::endl;
}
start_receive();
}
-uint16_t Pinger::get_identifier()
+uint16_t BoostPinger::get_identifier()
{
return static_cast<uint16_t> ( ::getpid() );
}
#include <boost/asio.hpp>
+#include "pinger.h"
+
using boost::asio::ip::address;
using boost::asio::ip::icmp;
using boost::asio::deadline_timer;
namespace posix_time = boost::posix_time;
//-----------------------------------------------------------------------------
-// Pinger
+// BoostPinger
//-----------------------------------------------------------------------------
-class Pinger
+class BoostPinger : public Pinger
{
public:
- Pinger( boost::asio::io_service& io_service, const char* destination );
- virtual ~Pinger();
+ BoostPinger( boost::asio::io_service& io_service );
+ virtual ~BoostPinger();
+
+ void ping( const Host &host );
private:
void start_send();
static uint16_t get_identifier();
- icmp::resolver m_resolver;
- icmp::endpoint m_destination;
- icmp::socket m_socket;
- deadline_timer m_timer;
- uint16_t m_sequence_number;
- posix_time::ptime m_time_sent;
- boost::asio::streambuf m_reply_buffer;
- std::size_t m_num_replies;
+ icmp::resolver resolver;
+ icmp::endpoint destination_endpoint;
+ icmp::socket socket;
+ deadline_timer timer;
+ uint16_t sequence_number;
+ posix_time::ptime time_sent;
+ boost::asio::streambuf reply_buffer;
+ std::size_t num_replies;
+
};
#endif /* PINGER_HPP */
--- /dev/null
+#include "host.h"
+
+Host::Host( std::string address )
+{
+}
+
+Host::~Host()
+{
+}
+
+std::string Host::getDns() const
+{
+ return dns;
+}
+
+void Host::setDns( std::string dns )
+{
+ this->dns = dns;
+}
+
+uint32_t Host::getInterval() const
+{
+ return interval;
+}
+
+void Host::setInterval( uint32_t interval )
+{
+ this->interval = interval;
+}
+
+std::string Host::getIp() const
+{
+ return ip;
+}
+
+void Host::setIp( std::string ip )
+{
+ this->ip = ip;
+}
+std::vector<std::string> Host::getOptions() const
+{
+ return options;
+}
+
+void Host::setOptions( std::vector<std::string> options )
+{
+ this->options = options;
+}
+
+uint16_t Host::getPort() const
+{
+ return port;
+}
+
+void Host::setPort( uint16_t port )
+{
+ this->port = port;
+}
--- /dev/null
+#ifndef HOST_H_
+#define HOST_H_
+
+#include <string>
+#include <vector>
+
+#include <stdint.h>
+
+class Host
+{
+public:
+ Host( std::string address );
+ virtual ~Host();
+
+ std::string getDns() const;
+ void setDns( std::string dns );
+
+ uint32_t getInterval() const;
+ void setInterval( uint32_t interval );
+
+ std::string getIp() const;
+ void setIp( std::string ip );
+
+ std::vector<std::string> getOptions() const;
+ void setOptions( std::vector<std::string> options );
+
+ uint16_t getPort() const;
+ void setPort( uint16_t port );
+
+private:
+ std::string ip;
+ std::string dns;
+ uint16_t port;
+ uint32_t interval;
+ std::vector<std::string> options;
+
+};
+
+#endif /* HOST_H_ */
-#include "icmp_header.hpp"
+#include "icmp_header.h"
IcmpHeader::IcmpHeader()
{
- std::fill( m_rep, m_rep + sizeof(m_rep), 0 );
+ std::fill( rep, rep + sizeof(rep), 0 );
}
unsigned char IcmpHeader::type() const
{
- return m_rep[ 0 ];
+ return rep[ 0 ];
}
unsigned char IcmpHeader::code() const
{
- return m_rep[ 1 ];
+ return rep[ 1 ];
}
unsigned short IcmpHeader::checksum() const
void IcmpHeader::type( unsigned char n )
{
- m_rep[ 0 ] = n;
+ rep[ 0 ] = n;
}
void IcmpHeader::code( unsigned char n )
{
- m_rep[ 1 ] = n;
+ rep[ 1 ] = n;
}
void IcmpHeader::checksum( unsigned short n )
std::istream& operator>>( std::istream& is, IcmpHeader& header )
{
- return is.read( reinterpret_cast<char*> ( header.m_rep ), 8 );
+ return is.read( reinterpret_cast<char*> ( header.rep ), 8 );
}
std::ostream& operator<<( std::ostream& os, const IcmpHeader& header )
{
- return os.write( reinterpret_cast<const char*> ( header.m_rep ), 8 );
+ return os.write( reinterpret_cast<const char*> ( header.rep ), 8 );
}
unsigned short IcmpHeader::decode( int a, int b ) const
{
- return (m_rep[ a ] << 8) + m_rep[ b ];
+ return (rep[ a ] << 8) + rep[ b ];
}
void IcmpHeader::encode( int a, int b, unsigned short n )
{
- m_rep[ a ] = static_cast<unsigned char> ( n >> 8 );
- m_rep[ b ] = static_cast<unsigned char> ( n & 0xFF );
+ rep[ a ] = static_cast<unsigned char> ( n >> 8 );
+ rep[ b ] = static_cast<unsigned char> ( n & 0xFF );
}
unsigned short decode( int a, int b ) const;
void encode( int a, int b, unsigned short n );
- unsigned char m_rep[ 8 ];
+ unsigned char rep[ 8 ];
};
template<typename Iterator>
-#include "ipv4_header.hpp"
+#include "ipv4_header.h"
Ipv4Header::Ipv4Header()
{
- std::fill( m_rep, m_rep + sizeof(m_rep), 0 );
+ std::fill( rep, rep + sizeof(rep), 0 );
}
unsigned char Ipv4Header::version() const
{
- return (m_rep[ 0 ] >> 4) & 0xF;
+ return (rep[ 0 ] >> 4) & 0xF;
}
unsigned short Ipv4Header::header_length() const
{
- return (m_rep[ 0 ] & 0xF) * 4;
+ return (rep[ 0 ] & 0xF) * 4;
}
unsigned char Ipv4Header::type_of_service() const
{
- return m_rep[ 1 ];
+ return rep[ 1 ];
}
unsigned short Ipv4Header::total_length() const
bool Ipv4Header::dont_fragment() const
{
- return (m_rep[ 6 ] & 0x40) != 0;
+ return (rep[ 6 ] & 0x40) != 0;
}
bool Ipv4Header::more_fragments() const
{
- return (m_rep[ 6 ] & 0x20) != 0;
+ return (rep[ 6 ] & 0x20) != 0;
}
unsigned short Ipv4Header::fragment_offset() const
unsigned int Ipv4Header::time_to_live() const
{
- return m_rep[ 8 ];
+ return rep[ 8 ];
}
unsigned char Ipv4Header::protocol() const
{
- return m_rep[ 9 ];
+ return rep[ 9 ];
}
unsigned short Ipv4Header::header_checksum() const
boost::asio::ip::address_v4 Ipv4Header::source_address() const
{
boost::asio::ip::address_v4::bytes_type bytes = { {
- m_rep[ 12 ],
- m_rep[ 13 ],
- m_rep[ 14 ],
- m_rep[ 15 ] } };
+ rep[ 12 ],
+ rep[ 13 ],
+ rep[ 14 ],
+ rep[ 15 ] } };
return boost::asio::ip::address_v4( bytes );
}
boost::asio::ip::address_v4 Ipv4Header::destination_address() const
{
boost::asio::ip::address_v4::bytes_type bytes = { {
- m_rep[ 16 ],
- m_rep[ 17 ],
- m_rep[ 18 ],
- m_rep[ 19 ] } };
+ rep[ 16 ],
+ rep[ 17 ],
+ rep[ 18 ],
+ rep[ 19 ] } };
return boost::asio::ip::address_v4( bytes );
}
std::istream& operator>>( std::istream& is, Ipv4Header& header )
{
- is.read( reinterpret_cast<char*> ( header.m_rep ), 20 );
+ is.read( reinterpret_cast<char*> ( header.rep ), 20 );
if (header.version() != 4)
is.setstate( std::ios::failbit );
std::streamsize options_length = header.header_length() - 20;
if (options_length < 0 || options_length > 40)
is.setstate( std::ios::failbit );
else
- is.read( reinterpret_cast<char*> ( header.m_rep ) + 20, options_length );
+ is.read( reinterpret_cast<char*> ( header.rep ) + 20, options_length );
return is;
}
unsigned short Ipv4Header::decode( int a, int b ) const
{
- return (m_rep[ a ] << 8) + m_rep[ b ];
+ return (rep[ a ] << 8) + rep[ b ];
}
private:
unsigned short decode( int a, int b ) const;
- unsigned char m_rep[ 60 ];
+ unsigned char rep[ 60 ];
};
#endif // IPV4_HEADER_HPP
--- /dev/null
+#include "configurationreader.h"
+
+#include "pingcheck.h"
+
+PingCheck::PingCheck() :
+ configuration( NULL )
+{
+
+}
+
+PingCheck::~PingCheck()
+{
+}
+
+void PingCheck::read_configuration()
+{
+ // sends the program command line to be parsed by the configuration reader
+ // check if it reads correctly
+
+ //
+ //
+ //
+ //
+ //
+ //
+ //
+ //
+ //
+ //
+ //
+}
+
+void PingCheck::init_ping_managers()
+{
+ // starts N ping managers with a host and an interval, this was read in configuration
+ // for each host in configuration
+ //
+ //
+ //
+ //
+ //
+ //
+ //
+}
--- /dev/null
+#ifndef PINGCHECK_H_
+#define PINGCHECK_H_
+
+#include <map>
+
+#include "configuration.h"
+#include "pingmanager.h"
+
+class PingCheck
+{
+public:
+ PingCheck();
+ virtual ~PingCheck();
+
+ void read_configuration();
+ void init_ping_managers();
+
+private:
+ Configuration *configuration;
+ std::multimap<int, PingManager> ping_managers;
+
+};
+
+#endif /* PINGCHECK_H_ */
--- /dev/null
+#include "pinger.h"
+
+Pinger::Pinger()
+{
+}
+
+Pinger::~Pinger()
+{
+}
--- /dev/null
+#ifndef PINGER_H_
+#define PINGER_H_
+
+#include <string>
+
+#include "host.h"
+
+class Pinger
+{
+public:
+ Pinger();
+ virtual ~Pinger();
+
+ virtual void ping( const Host &host ) = 0;
+
+};
+
+#endif /* PINGER_H_ */
--- /dev/null
+#include "pingmanager.h"
+
+PingManager::PingManager()
+{
+
+}
+
+PingManager::~PingManager()
+{
+}
+
+void PingManager::ping()
+{
+}
--- /dev/null
+#ifndef PINGMANAGER_H_
+#define PINGMANAGER_H_
+
+#include "pinger.h"
+#include "host.h"
+
+class PingManager
+{
+public:
+ PingManager();
+ virtual ~PingManager();
+
+ void ping();
+
+private:
+ Pinger *pinger;
+ uint32_t interval;
+ Host *host;
+
+};
+
+#endif /* PINGMANAGER_H_ */