Commit | Line | Data |
---|---|---|
0c0bb697 TJ |
1 | // Boost pinger (c) 2011 by Guilherme Maciel Ferreira / Intra2net AG |
2 | // Based upon work copyright (c) 2003-2010 Christopher M. Kohlhoff (ping.cpp) | |
bd4da22b | 3 | // Modified 2014 by Christian Herdtweck, Intra2net AG |
0c0bb697 TJ |
4 | // |
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) | |
f5c0f0d0 GMF |
8 | #ifndef ICMP_PINGER_H |
9 | #define ICMP_PINGER_H | |
4ea9706c | 10 | |
238da857 GMF |
11 | #include <stdint.h> |
12 | ||
d8b4a7e7 | 13 | #include <string> |
f076f8d4 | 14 | #include <set> |
d8b4a7e7 | 15 | |
4ea9706c | 16 | #include <boost/asio.hpp> |
24e706c4 | 17 | #include <boost/function.hpp> |
1ece191b | 18 | #include <boost/shared_ptr.hpp> |
9c55ecd3 | 19 | |
3c18d612 | 20 | #include "host/pinger.h" |
f5c0f0d0 | 21 | #include "host/pingstatus.h" |
af68f845 | 22 | #include "icmp/icmppacket.h" |
f076f8d4 CH |
23 | |
24 | ||
25 | using boost::asio::ip::icmp; | |
1ece191b CH |
26 | |
27 | class IcmpPinger; | |
28 | typedef boost::shared_ptr<IcmpPinger> IcmpPingerItem; | |
e08ab6c9 | 29 | |
f076f8d4 CH |
30 | class IcmpPacketDistributor; |
31 | typedef boost::shared_ptr<IcmpPacketDistributor> IcmpPacketDistributorItem; | |
32 | ||
f076f8d4 CH |
33 | typedef boost::shared_ptr<icmp::socket> SocketItem; |
34 | ||
35 | //----------------------------------------------------------------------------- | |
36 | // IcmpPacketDistributor | |
37 | //----------------------------------------------------------------------------- | |
38 | ||
39 | ||
40 | class IcmpPacketDistributor | |
41 | { | |
42 | public: | |
43 | bool register_pinger( const IcmpPingerItem &new_pinger ); | |
44 | bool unregister_pinger( const IcmpPingerItem &old_pinger ); | |
45 | ||
46 | SocketItem get_socket() const; | |
47 | ||
48 | static IcmpPacketDistributorItem get_distributor( | |
49 | const icmp::socket::protocol_type &protocol, | |
50 | const std::string &network_interface, | |
51 | const IoServiceItem io_serv | |
52 | ); | |
53 | ||
54 | static IcmpPacketDistributorItem get_distributor( | |
55 | const icmp::socket::protocol_type &protocol, | |
56 | const std::string &network_interface | |
57 | ); | |
58 | ||
59 | static void clean_up_all(); | |
60 | ||
61 | ~IcmpPacketDistributor(); | |
62 | ||
63 | private: | |
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 | |
69 | ); | |
70 | IcmpPacketDistributor(IcmpPacketDistributor const&); | |
71 | void operator=(IcmpPacketDistributor const&); | |
72 | ||
73 | void register_receive_handler(); | |
74 | void handle_receive( const boost::system::error_code &error, | |
75 | const size_t &bytes_transferred ); | |
76 | void clean_up(); | |
77 | ||
78 | private: | |
f076f8d4 CH |
79 | /// Network layer protocol used to ping, IPv4 or IPv6 |
80 | icmp::socket::protocol_type Protocol; | |
81 | ||
e0a99ac4 CH |
82 | /// The socket object |
83 | SocketItem Socket; | |
84 | ||
f076f8d4 CH |
85 | /// The buffer where the data received will be placed |
86 | boost::asio::streambuf ReplyBuffer; | |
87 | ||
88 | std::set<IcmpPingerItem> PingerList; | |
89 | ||
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; | |
94 | ||
95 | struct InstanceIdentifierComparator | |
96 | { | |
97 | bool operator() ( const DistributorInstanceIdentifier &a, | |
98 | const DistributorInstanceIdentifier &b ) const ; | |
99 | }; | |
100 | ||
101 | typedef std::map<DistributorInstanceIdentifier, IcmpPacketDistributorItem, | |
102 | InstanceIdentifierComparator> map_type; | |
103 | /// Instances, one for each (protocol, interface) - pair | |
104 | static map_type Instances; | |
105 | }; | |
106 | ||
4ea9706c | 107 | //----------------------------------------------------------------------------- |
87e525ff | 108 | // IcmpPinger |
4ea9706c GMF |
109 | //----------------------------------------------------------------------------- |
110 | ||
c5e4bfa1 | 111 | /** |
6cd5c2de | 112 | * @brief This class performs an ICMP ping to host using Boost Asio. |
ed1931dc | 113 | * Scope: one object per host. |
c5e4bfa1 | 114 | */ |
3c18d612 | 115 | class IcmpPinger : public Pinger |
4ea9706c GMF |
116 | { |
117 | public: | |
4606d2b1 | 118 | static PingerItem create( |
365036be | 119 | const IoServiceItem io_serv, |
fc3754b0 | 120 | const boost::asio::ip::icmp::socket::protocol_type &protocol, |
d8b4a7e7 | 121 | const std::string &source_network_interface, |
fc444c5a | 122 | const int echo_reply_timeout_in_sec |
e08ab6c9 | 123 | ); |
4606d2b1 | 124 | |
87e525ff | 125 | virtual ~IcmpPinger(); |
ced28dc7 | 126 | |
9a34f743 | 127 | virtual void ping( |
23f51766 | 128 | const boost::asio::ip::address &destination_ip, |
238da857 | 129 | const uint16_t destination_port, |
20976656 | 130 | boost::function<void(bool)> ping_done_callback |
87e525ff | 131 | ); |
83d87183 | 132 | |
5a9bc2d1 CH |
133 | virtual void stop_pinging(); |
134 | ||
f076f8d4 CH |
135 | bool handle_receive_icmp_packet(const IcmpPacketItem icmp_packet, |
136 | const size_t bytes_transferred | |
137 | ); | |
138 | ||
83d87183 | 139 | private: |
4606d2b1 CH |
140 | IcmpPinger( |
141 | const IoServiceItem io_serv, | |
142 | const boost::asio::ip::icmp::socket::protocol_type &protocol, | |
f076f8d4 CH |
143 | const int echo_reply_timeout_in_sec, |
144 | const IcmpPacketDistributorItem distributor | |
4606d2b1 CH |
145 | ); |
146 | ||
23f51766 | 147 | void set_destination_endpoint(const boost::asio::ip::address &destination); |
5c670f6b | 148 | |
ba5d41fe CH |
149 | bool start_send(); |
150 | bool send_echo_request( const IcmpPacketItem icmp_packet ); | |
2210b856 | 151 | void schedule_timeout_echo_reply(); |
d26dce11 | 152 | void handle_timeout(const boost::system::error_code &error); |
a8d411d6 | 153 | |
f5c0f0d0 | 154 | void set_ping_status( PingStatus ping_status ); |
83d87183 | 155 | |
2d591235 | 156 | private: |
1ece191b CH |
157 | IcmpPacketDistributorItem PacketDistributor; |
158 | ||
3b668576 | 159 | /// The destination host |
a7c2eb51 | 160 | boost::asio::ip::icmp::endpoint DestinationEndpoint; |
5b008ada GMF |
161 | /// Network layer protocol used to ping, IPv4 or IPv6 |
162 | boost::asio::ip::icmp::socket::protocol_type Protocol; | |
3b668576 | 163 | /// The timer of ICMP packet receive, triggers the timeout to avoid infinite |
d3e8a9f9 | 164 | /// wait |
2b5520bc | 165 | boost::asio::deadline_timer IcmpPacketReceiveTimer; |
55978089 TJ |
166 | /// ICMP packet identifier |
167 | uint16_t Identifier; | |
d3e8a9f9 | 168 | /// ICMP packet sequence_number |
33f408b1 | 169 | uint16_t SequenceNumber; |
3b668576 | 170 | /// The time when the last ICMP packet was sent |
33f408b1 | 171 | boost::posix_time::ptime TimeSent; |
03f12d85 | 172 | /// Flag to indicate if we got a reply or not |
0697580f | 173 | bool ReplyReceived; |
3b668576 | 174 | /// The amount of time to wait for the reply |
fc444c5a | 175 | int EchoReplyTimeoutInSec; |
3b668576 | 176 | /// The status of the pinger |
f5c0f0d0 | 177 | PingStatus PingerStatus; |
03f12d85 | 178 | /// Callback to notify when the ping is done (got reply/timeout) |
24e706c4 | 179 | boost::function< void(bool) > PingDoneCallback; |
20a8838c CH |
180 | /// prefix to logging output lines |
181 | std::string LogPrefix; | |
4ea9706c GMF |
182 | }; |
183 | ||
f5c0f0d0 | 184 | #endif // ICMP_PINGER_H |