1 // Boost pinger (c) 2011 by Guilherme Maciel Ferreira / Intra2net AG
2 // Based upon work copyright (c) 2003-2010 Christopher M. Kohlhoff (ping.cpp)
3 // Modified 2014 by Christian Herdtweck, Intra2net AG
5 // Distributed under the Boost Software License, Version 1.0.
6 // (See accompanying file LICENSE_1_0.txt or copy at
7 // http://www.boost.org/LICENSE_1_0.txt)
16 #include <boost/asio.hpp>
17 #include <boost/function.hpp>
18 #include <boost/shared_ptr.hpp>
20 #include "host/pinger.h"
21 #include "host/pingstatus.h"
22 #include "icmp/icmppacket.h"
25 using boost::asio::ip::icmp;
28 typedef boost::shared_ptr<IcmpPinger> IcmpPingerItem;
30 class IcmpPacketDistributor;
31 typedef boost::shared_ptr<IcmpPacketDistributor> IcmpPacketDistributorItem;
33 typedef boost::shared_ptr<icmp::socket> SocketItem;
35 //-----------------------------------------------------------------------------
36 // IcmpPacketDistributor
37 //-----------------------------------------------------------------------------
40 class IcmpPacketDistributor
43 bool register_pinger( const IcmpPingerItem &new_pinger );
44 bool unregister_pinger( const IcmpPingerItem &old_pinger );
46 SocketItem get_socket() const;
48 static IcmpPacketDistributorItem get_distributor(
49 const icmp::socket::protocol_type &protocol,
50 const std::string &network_interface,
51 const IoServiceItem io_serv
54 static IcmpPacketDistributorItem get_distributor(
55 const icmp::socket::protocol_type &protocol,
56 const std::string &network_interface
59 static void clean_up_all();
61 ~IcmpPacketDistributor();
64 // hide away constructor, copy constructor and assignment operator
65 IcmpPacketDistributor(
66 const icmp::socket::protocol_type &protocol,
67 const std::string &network_interface,
68 const IoServiceItem io_serv
70 IcmpPacketDistributor(IcmpPacketDistributor const&);
71 void operator=(IcmpPacketDistributor const&);
73 void register_receive_handler();
74 void handle_receive( const boost::system::error_code &error,
75 const size_t &bytes_transferred );
79 /// Network layer protocol used to ping, IPv4 or IPv6
80 icmp::socket::protocol_type Protocol;
85 /// The buffer where the data received will be placed
86 boost::asio::streambuf ReplyBuffer;
88 std::set<IcmpPingerItem> PingerList;
90 // for each IP protocol (v4/v6) and each network interface (string),
91 // there can only be one IcmpPacketDistributor instance
92 typedef std::pair<icmp::socket::protocol_type, std::string>
93 DistributorInstanceIdentifier;
95 struct InstanceIdentifierComparator
97 bool operator() ( const DistributorInstanceIdentifier &a,
98 const DistributorInstanceIdentifier &b ) const ;
101 typedef std::map<DistributorInstanceIdentifier, IcmpPacketDistributorItem,
102 InstanceIdentifierComparator> map_type;
103 /// Instances, one for each (protocol, interface) - pair
104 static map_type Instances;
107 //-----------------------------------------------------------------------------
109 //-----------------------------------------------------------------------------
112 * @brief This class performs an ICMP ping to host using Boost Asio.
113 * Scope: one object per host.
115 class IcmpPinger : public Pinger
118 static PingerItem create(
119 const IoServiceItem io_serv,
120 const boost::asio::ip::icmp::socket::protocol_type &protocol,
121 const std::string &source_network_interface,
122 const int echo_reply_timeout_in_sec
125 virtual ~IcmpPinger();
128 const std::string &destination_ip,
129 const uint16_t destination_port,
130 boost::function<void(bool)> ping_done_callback
133 virtual void stop_pinging();
135 bool handle_receive_icmp_packet(const IcmpPacketItem icmp_packet,
136 const size_t bytes_transferred
141 const IoServiceItem io_serv,
142 const boost::asio::ip::icmp::socket::protocol_type &protocol,
143 const int echo_reply_timeout_in_sec,
144 const IcmpPacketDistributorItem distributor
147 void set_destination_endpoint( const std::string &destination_ip );
150 bool send_echo_request( const IcmpPacketItem icmp_packet );
151 void schedule_timeout_echo_reply();
152 void handle_timeout(const boost::system::error_code &error);
154 void set_ping_status( PingStatus ping_status );
157 IcmpPacketDistributorItem PacketDistributor;
159 /// The destination host
160 boost::asio::ip::icmp::endpoint DestinationEndpoint;
161 /// Network layer protocol used to ping, IPv4 or IPv6
162 boost::asio::ip::icmp::socket::protocol_type Protocol;
163 /// The timer of ICMP packet receive, triggers the timeout to avoid infinite
165 boost::asio::deadline_timer IcmpPacketReceiveTimer;
166 /// ICMP packet identifier
168 /// ICMP packet sequence_number
169 uint16_t SequenceNumber;
170 /// The time when the last ICMP packet was sent
171 boost::posix_time::ptime TimeSent;
172 /// Flag to indicate if we got a reply or not
174 /// The amount of time to wait for the reply
175 int EchoReplyTimeoutInSec;
176 /// The status of the pinger
177 PingStatus PingerStatus;
178 /// Callback to notify when the ping is done (got reply/timeout)
179 boost::function< void(bool) > PingDoneCallback;
182 #endif // ICMP_PINGER_H