I develop simple traceroute program with help boost_asio
. I use this example. I little change this example to implement traceroute
instead of ping
.
pinger(boost::asio::io_service& io_service, const char* destination)
: resolver_(io_service), socket_(io_service, icmp::v4()),
timer_(io_service), sequence_number_(0), num_replies_(0)
{
boost::asio::ip::unicast::hops option(%1%); // 1 is a param
socket_.set_option(option);
icmp::resolver::query query(icmp::v4(), destination, "");
destination_ = *resolver_.resolve(query);
start_send();
start_receive();
}
I have a problem. When time to live
is less, than it needs, I have no any response. I wish to get something like this:
C:\Users\>ping 91.92.100.254 -i 2
Pinging 91.92.100.254 with 32 bytes of data:
Reply from 10.110.50.251: TTL expired in transit.
Reply from 10.110.50.251: TTL expired in transit.
Reply from 10.110.50.251: TTL expired in transit.
I haven't used boost asio much (or boost, for that matter), so I'm not certain which handler the TTL expiration error would be sent to, but this should get you on the right track...
Where you begin waiting for your reply, add the _1 placeholder to pass the socket error to your handle_receive method:
// Wait for a reply. We prepare the buffer to receive up to 64KB.
// Note that you can use boost::asio::placeholders::error in place of _1
// and boost::asio::bytes_transferred in place of _2.
socket_.async_receive(reply_buffer_.prepare(65536),
boost::bind(&pinger::handle_receive, this, _1, _2));
Also change your handle_receive header to accept the error code
void handle_receive(const boost::system::error_code& error, std::size_t length) {
if (error) {
// Handle error
}
else {
// Handle normally
}
}
The error may get passed into the timeout handler. In this case, you can check the error code in there as well:
// Add _1 placeholder
timer_.async_wait(boost::bind(&pinger::handle_timeout, this, _1));
Likewise, you'll need to add that argument to your handler:
void handle_timeout(const boost::system::error_code& error) {
if (error) {
// Handle error
}
else {
// Handle normally
}
}