/* * 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; }
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....
[<>]