- ping.cpp
/*
* ping.cpp
*
* Author, Copyright: Oleg Borodin <onborodin@gmail.com>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
* MA 02110-1301, USA.
*
*/
#include <iostream>
#include <boost/asio.hpp>
#include <boost/bind.hpp>
#include <boost/array.hpp>
#include <istream>
#include <iostream>
#include <ostream>
using namespace boost::asio;
struct icmp_header {
uint8_t icmp_type;
uint8_t icmp_code;
uint16_t icmp_cksum;
uint16_t icmp_id;
uint16_t icmp_seq;
};
class icmp_packet {
public:
icmp_header header;
friend std::ostream& operator<<(std::ostream& ostream, icmp_packet& packet);
void checksum() {
const uint16_t * const data = (uint16_t *)&header;
size_t byte_sz = sizeof(header);
uint32_t accu = 0;
for (size_t i = 0; i < (byte_sz >> 1); ++i) {
accu = accu + data[i];
}
while (accu >> 16) {
accu = (accu & 0xffff) + (accu >> 16);
}
const uint16_t checksum = ~accu;
header.icmp_cksum = checksum;
}
};
std::ostream& operator<<(std::ostream& ostream, icmp_packet& packet) {
return ostream.write((char *)(&packet.header), sizeof(packet.header));
}
#define ICMP_ECHOREPLY 0
#define ICMP_ECHO 8
#define ICMP_CODE 0
int main(int argc, char **argv) {
io_service io_service;
ip::icmp::resolver resolver(io_service);
ip::icmp::resolver::query query(ip::icmp::v4(), "wiki.unix7.org", "");
ip::icmp::resolver::iterator iter = resolver.resolve(query);
ip::icmp::endpoint destination = *iter;
std::cout
<< "# dest address is "
<< destination.address().to_string()
<< std::endl;
std::time_t now = std::time(0);
std::cout << std::ctime(&now);
ip::icmp::endpoint endpoint(ip::icmp::v4(), 0);
try {
ip::icmp::socket socket(io_service, endpoint);
icmp_packet icmp_packet;
icmp_packet.header.icmp_type = ICMP_ECHO;
icmp_packet.header.icmp_code = ICMP_CODE;
icmp_packet.header.icmp_id = htons(1234);
icmp_packet.header.icmp_cksum = 0;
icmp_packet.header.icmp_seq = htons(4567);
icmp_packet.checksum();
boost::asio::streambuf request_buffer;
std::ostream ostream(&request_buffer);
ostream << icmp_packet;
socket.send_to(request_buffer.data(), destination);
}
catch (std::exception& e) {
std::cout << "# exception: " << e.what() << "\n";
return 0;
}
return 0;
}
Result network dump
16:28:30.892293 IP (tos 0x0, ttl 64, id 35762, offset 0, flags [none], proto ICMP (1), length 28)
192.168.46.10 > vbsd05.unix7.org: ICMP echo request, id 1234, seq 4567, length 8
0x0000: 4500 001c 8bb2 0000 4001 cabb c0a8 2e0a E.......@.......
0x0010: 5dab d815 0800 e156 04d2 11d7 ]......V....
16:28:30.940162 IP (tos 0x0, ttl 55, id 43562, offset 0, flags [none], proto ICMP (1), length 28)
vbsd05.unix7.org > 192.168.46.10: ICMP echo reply, id 1234, seq 4567, length 8
0x0000: 4500 001c aa2a 0000 3701 b543 5dab d815 E....*..7..C]...
0x0010: c0a8 2e0a 0000 e956 04d2 11d7 .......V....




