User Tools

Site Tools


Differences

This shows you the differences between two versions of the page.

Link to this comparison view

cpp:rawsocket [2019-05-28 15:26]
cpp:rawsocket [2020-02-15 00:57] (current)
Line 1: Line 1:
 +
 +<code c++ ping.cpp>​
 +/*
 + * ping.cpp
 + *
 + * Copyright 2004-2019 Oleg Borodin <​borodin@unix7.org>​
 + *
 + * 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;
 +}
 +</​code>​
 +
 +===Result network dump===
 +
 +<​file>​
 +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....
 +</​file>​
 +
 +----
 +[<>]