boost::function<void(bool)> ping_done_callback
) = 0;
+protected:
+ Pinger();
+ Pinger( const Pinger &other );
+ virtual ~Pinger();
+
+ Pinger& operator=( const Pinger &other );
+
};
- #endif /* PINGER_H */
+ #endif // PINGER_H
{
BOOST_ASSERT( !protocol_string.empty() );
+ // convert to uppercase to allow the protocol to be case insensitive
+ string protocol_uppercase_string( protocol_string );
+ transform( protocol_string.begin(), protocol_string.end(),
+ protocol_uppercase_string.begin(),
+ ::toupper );
+
// TODO move to an init method
protocol_string_map[ "ICMP" ] = PingProtocol_ICMP;
+ protocol_string_map[ "ICMPv6" ] = PingProtocol_ICMPv6;
protocol_string_map[ "TCP" ] = PingProtocol_TCP;
+ protocol_string_map[ "TCP_IPv6" ] = PingProtocol_TCP_IPv6;
- return protocol_string_map[ protocol_string ];
+ return protocol_string_map[ protocol_uppercase_string ];;
}
enum PingProtocol
{
PingProtocol_First = 0,
- PingProtocol_ICMP = 0,
+ PingProtocol_ICMP = PingProtocol_First,
+ PingProtocol_ICMPv6,
PingProtocol_TCP,
- PingProtocol_Last = PingProtocol_TCP
+ PingProtocol_TCP_IPv6,
+ PingProtocol_Last = PingProtocol_TCP_IPv6
};
- PingProtocol get_ping_protocol_from_string( std::string protocol_string );
+ PingProtocol get_ping_protocol_from_string( const std::string & protocol_string );
- #endif /* PINGPROTOCOL_H */
+ #endif // PING_PROTOCOL_H
#ifndef ICMP_TYPE_H
#define ICMP_TYPE_H
-enum IcmpType
+enum Icmpv4Type
{
- IcmpType_EchoReply = 0,
- IcmpType_DestinationUnreachable = 3,
- IcmpType_SourceQuench = 4,
- IcmpType_Redirect = 5,
- IcmpType_EchoRequest = 8,
- IcmpType_TimeExceeded = 11,
- IcmpType_ParameterProblem = 12,
- IcmpType_TimestampRequest = 13,
- IcmpType_TimestampReply = 14,
- IcmpType_InfoRequest = 15,
- IcmpType_InfoReply = 16,
- IcmpType_AddressRequest = 17,
- IcmpType_AddressReply = 18,
- IcmpType_InvalidLast = 42,
- IcmpType_Generic = 43
+ Icmpv4Type_EchoReply = 0,
+ Icmpv4Type_DestinationUnreachable = 3,
+ Icmpv4Type_SourceQuench = 4,
+ Icmpv4Type_Redirect = 5,
+ Icmpv4Type_EchoRequest = 8,
+ Icmpv4Type_TimeExceeded = 11,
+ Icmpv4Type_ParameterProblem = 12,
+ Icmpv4Type_TimestampRequest = 13,
+ Icmpv4Type_TimestampReply = 14,
+ Icmpv4Type_InfoRequest = 15,
+ Icmpv4Type_InfoReply = 16,
+ Icmpv4Type_AddressRequest = 17,
+ Icmpv4Type_AddressReply = 18,
+ Icmpv4Type_InvalidLast = 42,
+ Icmpv4Type_Generic = 43
+};
+
+enum Icmpv6Type
+{
+ Icmpv6Type_First = 0,
+ // ICMPv6 Error Messages
+ Icmpv6Type_DestinationUnreachable = 1,
+ Icmpv6Type_PacketTooBig = 2,
+ Icmpv6Type_TimeExceeded = 3,
+ Icmpv6Type_ParameterProblem = 4,
+ // ICMPv6 Informational Messages
+ Icmpv6Type_EchoRequest = 128,
+ Icmpv6Type_EchoReply = 129,
+ Icmpv6Type_RouterSolicitation = 133,
+ Icmpv6Type_RouterAdvertisement = 134,
+ Icmpv6Type_NeighborSolicitation = 135,
+ Icmpv6Type_NeighborAdvertisement = 136,
+ Icmpv6Type_RedirectMessage = 137,
+ Icmpv6Type_RouterRenumbering = 138,
+ Icmpv6Type_ICMPNodeInformationQuery = 139,
+ Icmpv6Type_ICMPNodeInformationResponse = 140,
+ Icmpv6Type_InverseNeighborDiscoverySolicitationMessage = 141,
+ Icmpv6Type_InverseNeighborDiscoveryAdvertisementMessage = 142,
+ Icmpv6Type_MulticastListenerDiscovery = 143,
+ Icmpv6Type_HomeAgentAddressDiscoveryRequestMessage = 144,
+ Icmpv6Type_HomeAgentAddressDiscoveryReplyMessage = 145,
+ Icmpv6Type_MobilePrefixSolicitation = 146,
+ Icmpv6Type_MobilePrefixAdvertisement = 147,
+ Icmpv6Type_CertificationPathSolicitation = 148,
+ Icmpv6Type_CertificationPathAdvertisement = 149,
+ Icmpv6Type_MulticastRouterAdvertisement = 151,
+ Icmpv6Type_MulticastRouterSolicitation = 152,
+ Icmpv6Type_MulticastRouterTermination = 153,
+ Icmpv6Type_InvalidLast = 255,
+ Icmpv6Type_Generic
};
- #endif /* ICMP_TYPE_H */
+ #endif // ICMP_TYPE_H
--- /dev/null
+// Copyright (c) 2003-2010 Christopher M. Kohlhoff
+// Modifications (c) 2011 by Guilherme Maciel Ferreira / Intra2net AG
+//
+// Distributed under the Boost Software License, Version 1.0.
+// (See accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+#include "icmp/icmpv6packet.h"
+
+#include <iostream>
+
+#include <logfunc.hpp>
+
+using namespace std;
+using boost::asio::ip::address;
+using boost::date_time::time_resolution_traits_adapted64_impl;
+using boost::posix_time::ptime;
+using boost::posix_time::microsec_clock;
+using I2n::Logger::GlobalLogger;
+
+//-----------------------------------------------------------------------------
+// Icmpv6Packet
+//-----------------------------------------------------------------------------
+
+/**
+ * @brief Default constructor.
+ */
+Icmpv6Packet::Icmpv6Packet() :
+ IpHeader(),
+ IcmpPayloadHeader(),
+ IcmpPayloadData()
+{
+}
+
+/**
+ * @brief Parameterized constructor.
+ *
+ * @param icmp_header The ICMP header.
+ * @param icmp_data The ICMP payload data.
+ */
+Icmpv6Packet::Icmpv6Packet(
+ const Icmpv6Header &icmp_header,
+ const IcmpData &icmp_data
+) :
+ IpHeader(),
+ IcmpPayloadHeader( icmp_header ),
+ IcmpPayloadData( icmp_data )
+{
+}
+
+/**
+ * @brief Destructor.
+ */
+Icmpv6Packet::~Icmpv6Packet()
+{
+}
+
+/**
+ * @brief Obtain the IP header.
+ *
+ * @return The IP header object.
+ */
+Ipv6Header Icmpv6Packet::get_ip_header() const
+{
+ return IpHeader;
+}
+
+/**
+ * @brief Obtain the ICMP header.
+ *
+ * @return The ICMP header object.
+ */
+Icmpv6Header Icmpv6Packet::get_icmp_header() const
+{
+ return IcmpPayloadHeader;
+}
+
+/**
+ * @brief Obtain the ICMP payload data.
+ *
+ * @return The ICMP data.
+ */
+IcmpData Icmpv6Packet::get_icmp_data() const
+{
+ return IcmpPayloadData;
+}
+
+/**
+ * @brief Convenience method to check if this packet, matching the arguments,
+ * is a echo reply.
+ *
+ * @param identifier The identifier.
+ * @param sequence_number The sequence number.
+ * @param source_address The source address.
+ *
+ * @return @c true if this packet is a echo reply, or @c false otherwise.
+ */
+bool Icmpv6Packet::match_echo_reply(
+ const uint16_t identifier,
+ const uint16_t sequence_number,
+ const address &source_address
+) const
+{
+ return match( Icmpv6Type_EchoReply, identifier, sequence_number, source_address );
+}
+
+/**
+ * @brief Convenience method to check if this packet, matching the arguments,
+ * is a destination unreachable.
+ *
+ * @param identifier The identifier.
+ * @param sequence_number The sequence number.
+ * @param source_address The source address.
+ *
+ * @return @c true if this packet is a destination unreachable, or @c false
+ * otherwise.
+ */
+bool Icmpv6Packet::match_destination_unreachable(
+ const uint16_t identifier,
+ const uint16_t sequence_number,
+ const address &source_address
+) const
+{
+ return match( Icmpv6Type_DestinationUnreachable, identifier, sequence_number, source_address );
+}
+
+/**
+ * @brief Check if this object matches with all the parameters.
+ *
+ * @param type The type of ICMP message.
+ * @param identifier The identifier.
+ * @param sequence_number The sequence number.
+ * @param source_address The source address.
+ *
+ * @return @c true if this matches all the parameters, or @c false if at least
+ * one does not match.
+ */
+bool Icmpv6Packet::match(
+ const Icmpv6Type type,
+ const uint16_t identifier,
+ const uint16_t sequence_number,
- const address &source_address
++ const address &/*source_address*/
+) const
+{
+ bool type_match = IcmpPayloadHeader.get_type() == type ? true : false;
+ bool identifier_match = IcmpPayloadHeader.get_identifier() == identifier ? true: false;
+ bool seq_num_match = IcmpPayloadHeader.get_sequence_number() == sequence_number ? true : false;
+#ifdef IPV6_DATA_PRESENT_IN_ISTREAM
+ // TODO operator>> does not read IpHeader, thus this object is not initialized
+ // must check why IPv6 data does not come in the istream like IPv4 data
+ bool address_match = IpHeader.get_source_address() == source_address ? true : false;
+
+ return ( type_match && identifier_match && seq_num_match && address_match );
+#else
+ return ( type_match && identifier_match && seq_num_match );
+#endif
+}
+
+/**
+ * @brief Prints the ICMP echo reply messages.
+ *
+ * @param bytes_transferred Number of bytes transferred.
+ * @param time_packet_sent The time when this packet was sent.
+ *
+ * @return void
+ */
+void Icmpv6Packet::print_echo_reply(
+ const size_t &bytes_transferred,
+ const ptime &time_packet_sent
+) const
+{
+ BOOST_ASSERT( get_icmp_header().get_type() == Icmpv6Type_EchoReply );
+
+ Ipv6Header ipv6_header = get_ip_header();
+ Icmpv6Header icmpv6_header = get_icmp_header();
+
+ size_t bytes_received = bytes_transferred - ipv6_header.get_payload_length();
+ string remote_address = ipv6_header.get_source_address().to_string();
+ uint16_t sequence_number = icmpv6_header.get_sequence_number();
+ int ttl = ipv6_header.get_hop_limit();
+ ptime now = microsec_clock::universal_time();
+ time_resolution_traits_adapted64_impl::int_type elapsed_time =
+ (now - time_packet_sent).total_milliseconds();
+
+ GlobalLogger.info() << bytes_received << " bytes "
+ << "from " << remote_address
+ << ": icmp_seq=" << sequence_number
+ << " ttl=" << ttl
+ << " time=" << elapsed_time << " ms" << endl;
+}
+
+/**
+ * @brief Prints the destination unreachable messages.
+ *
+ * @return void
+ */
+void Icmpv6Packet::print_destination_unreachable() const
+{
+ BOOST_ASSERT( get_icmp_header().get_type() == Icmpv6Type_DestinationUnreachable );
+
+ Ipv6Header ipv6_hdr = get_ip_header();
+ Icmpv6Header icmpv6_hdr = get_icmp_header();
+
+ string local_address = ipv6_hdr.get_destination_address().to_string();
+ uint16_t sequence_number = icmpv6_hdr.get_sequence_number();
+
+ GlobalLogger.info() << "From " << local_address
+ << " icmp_seq=" << sequence_number
+ << " Destination Net Unreachable" << endl;
+}
+
+bool Icmpv6Packet::read( istream &is )
+{
+ is.clear();
+
+ is >> *this;
+
+ return is.fail();
+}
+
+bool Icmpv6Packet::write( ostream &os ) const
+{
+ os.clear();
+
+ os << *this;
+
+ return os.fail();
+}
+
+istream& operator>>(
+ istream &is,
+ Icmpv6Packet &packet
+)
+{
+#ifdef IPV6_DATA_PRESENT_IN_ISTREAM
+ //TODO WHY IPv6 does not come like IPv4????
+ is >> packet.IpHeader >> packet.IcmpPayloadHeader >> packet.IcmpPayloadData;
+#else
+ is >> packet.IcmpPayloadHeader >> packet.IcmpPayloadData;
+#endif
+
+ return is;
+}
+
+ostream& operator<<(
+ ostream& os,
+ const Icmpv6Packet& packet
+)
+{
+ os << packet.IcmpPayloadHeader << packet.IcmpPayloadData;
+
+ return os;
+}
--- /dev/null
+/*
+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 LINKSTATUSANALYZER_H
- #define LINKSTATUSANALYZER_H
++#ifndef LINK_STATUS_ANALYZER_H
++#define LINK_STATUS_ANALYZER_H
+
+#include <string>
+
+#include <boost/shared_ptr.hpp>
+
+//-----------------------------------------------------------------------------
+// LinkStatusAnalyzer
+//-----------------------------------------------------------------------------
+
+/**
+ * @brief This is a fake link status class.
+ * Scope: one object for many hosts.
+ */
+class LinkStatusAnalyzer
+{
+public:
+ LinkStatusAnalyzer();
+ ~LinkStatusAnalyzer();
+
+ void notify_host_up( const std::string &host_address );
+ void notify_host_down( const std::string &host_address );
+
+};
+
+//-----------------------------------------------------------------------------
+
+LinkStatusAnalyzer::LinkStatusAnalyzer()
+{
+}
+
+LinkStatusAnalyzer::~LinkStatusAnalyzer()
+{
+}
+
+void LinkStatusAnalyzer::notify_host_up( const std::string &host_address )
+{
+}
+
+void LinkStatusAnalyzer::notify_host_down( const std::string &host_address )
+{
+}
+
+//-----------------------------------------------------------------------------
+// LinkStatusAnalyzerItem
+//-----------------------------------------------------------------------------
+
+typedef boost::shared_ptr<LinkStatusAnalyzer> LinkStatusAnalyzerItem;
+
- #endif // LINKSTATUSANALYZER_H
++#endif // LINK_STATUS_ANALYZER_H