Update pingcheck to work with cmake 3.28
[pingcheck] / src / icmp / icmppinger.h
... / ...
CommitLineData
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
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)
8#ifndef ICMP_PINGER_H
9#define ICMP_PINGER_H
10
11#include <stdint.h>
12
13#include <string>
14#include <set>
15
16#include <boost/asio.hpp>
17#include <boost/function.hpp>
18#include <boost/shared_ptr.hpp>
19
20#include "host/pinger.h"
21#include "host/pingstatus.h"
22#include "icmp/icmppacket.h"
23
24
25using boost::asio::ip::icmp;
26
27class IcmpPinger;
28typedef boost::shared_ptr<IcmpPinger> IcmpPingerItem;
29
30class IcmpPacketDistributor;
31typedef boost::shared_ptr<IcmpPacketDistributor> IcmpPacketDistributorItem;
32
33typedef boost::shared_ptr<icmp::socket> SocketItem;
34
35//-----------------------------------------------------------------------------
36// IcmpPacketDistributor
37//-----------------------------------------------------------------------------
38
39
40class IcmpPacketDistributor
41{
42public:
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
63private:
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
78private:
79 /// Network layer protocol used to ping, IPv4 or IPv6
80 icmp::socket::protocol_type Protocol;
81
82 /// The socket object
83 SocketItem Socket;
84
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
107//-----------------------------------------------------------------------------
108// IcmpPinger
109//-----------------------------------------------------------------------------
110
111/**
112 * @brief This class performs an ICMP ping to host using Boost Asio.
113 * Scope: one object per host.
114 */
115class IcmpPinger : public Pinger
116{
117public:
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
123 );
124
125 virtual ~IcmpPinger();
126
127 virtual void ping(
128 const boost::asio::ip::address &destination_ip,
129 const uint16_t destination_port,
130 boost::function<void(PingStatus,long)> ping_done_callback
131 );
132
133 virtual void stop_pinging();
134
135 bool handle_receive_icmp_packet(const IcmpPacketItem icmp_packet,
136 const size_t bytes_transferred
137 );
138
139private:
140 IcmpPinger(
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
145 );
146
147 void set_destination_endpoint(const boost::asio::ip::address &destination);
148
149 bool start_send();
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);
153
154 void set_ping_status( PingStatus ping_status );
155
156private:
157 IcmpPacketDistributorItem PacketDistributor;
158
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
164 /// wait
165 boost::asio::deadline_timer IcmpPacketReceiveTimer;
166 /// ICMP packet identifier
167 uint16_t 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
173 bool ReplyReceived;
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(PingStatus,long) > PingDoneCallback;
180 /// prefix to logging output lines
181 std::string LogPrefix;
182};
183
184#endif // ICMP_PINGER_H