From ff01b716711b97c2fcaa709ea97f7650f106aa10 Mon Sep 17 00:00:00 2001 From: Miodrag Milanovic Date: Fri, 7 Oct 2016 14:13:19 +0200 Subject: Added ASIO networking library (nw) --- .../asio/src/examples/cpp03/icmp/icmp_header.hpp | 94 ++++++++++++++++++++++ 1 file changed, 94 insertions(+) create mode 100644 3rdparty/asio/src/examples/cpp03/icmp/icmp_header.hpp (limited to '3rdparty/asio/src/examples/cpp03/icmp/icmp_header.hpp') diff --git a/3rdparty/asio/src/examples/cpp03/icmp/icmp_header.hpp b/3rdparty/asio/src/examples/cpp03/icmp/icmp_header.hpp new file mode 100644 index 00000000000..3b7b4bf5032 --- /dev/null +++ b/3rdparty/asio/src/examples/cpp03/icmp/icmp_header.hpp @@ -0,0 +1,94 @@ +// +// icmp_header.hpp +// ~~~~~~~~~~~~~~~ +// +// Copyright (c) 2003-2016 Christopher M. Kohlhoff (chris at kohlhoff dot com) +// +// Distributed under the Boost Software License, Version 1.0. (See accompanying +// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) +// + +#ifndef ICMP_HEADER_HPP +#define ICMP_HEADER_HPP + +#include +#include +#include + +// ICMP header for both IPv4 and IPv6. +// +// The wire format of an ICMP header is: +// +// 0 8 16 31 +// +---------------+---------------+------------------------------+ --- +// | | | | ^ +// | type | code | checksum | | +// | | | | | +// +---------------+---------------+------------------------------+ 8 bytes +// | | | | +// | identifier | sequence number | | +// | | | v +// +-------------------------------+------------------------------+ --- + +class icmp_header +{ +public: + enum { echo_reply = 0, destination_unreachable = 3, source_quench = 4, + redirect = 5, echo_request = 8, time_exceeded = 11, parameter_problem = 12, + timestamp_request = 13, timestamp_reply = 14, info_request = 15, + info_reply = 16, address_request = 17, address_reply = 18 }; + + icmp_header() { std::fill(rep_, rep_ + sizeof(rep_), 0); } + + unsigned char type() const { return rep_[0]; } + unsigned char code() const { return rep_[1]; } + unsigned short checksum() const { return decode(2, 3); } + unsigned short identifier() const { return decode(4, 5); } + unsigned short sequence_number() const { return decode(6, 7); } + + void type(unsigned char n) { rep_[0] = n; } + void code(unsigned char n) { rep_[1] = n; } + void checksum(unsigned short n) { encode(2, 3, n); } + void identifier(unsigned short n) { encode(4, 5, n); } + void sequence_number(unsigned short n) { encode(6, 7, n); } + + friend std::istream& operator>>(std::istream& is, icmp_header& header) + { return is.read(reinterpret_cast(header.rep_), 8); } + + friend std::ostream& operator<<(std::ostream& os, const icmp_header& header) + { return os.write(reinterpret_cast(header.rep_), 8); } + +private: + unsigned short decode(int a, int b) const + { return (rep_[a] << 8) + rep_[b]; } + + void encode(int a, int b, unsigned short n) + { + rep_[a] = static_cast(n >> 8); + rep_[b] = static_cast(n & 0xFF); + } + + unsigned char rep_[8]; +}; + +template +void compute_checksum(icmp_header& header, + Iterator body_begin, Iterator body_end) +{ + unsigned int sum = (header.type() << 8) + header.code() + + header.identifier() + header.sequence_number(); + + Iterator body_iter = body_begin; + while (body_iter != body_end) + { + sum += (static_cast(*body_iter++) << 8); + if (body_iter != body_end) + sum += static_cast(*body_iter++); + } + + sum = (sum >> 16) + (sum & 0xFFFF); + sum += (sum >> 16); + header.checksum(static_cast(~sum)); +} + +#endif // ICMP_HEADER_HPP -- cgit v1.2.3-70-g09d2