]> git.proxmox.com Git - ceph.git/blame - ceph/src/boost/libs/asio/example/cpp03/icmp/icmp_header.hpp
update sources to v12.2.3
[ceph.git] / ceph / src / boost / libs / asio / example / cpp03 / icmp / icmp_header.hpp
CommitLineData
7c673cae
FG
1//
2// icmp_header.hpp
3// ~~~~~~~~~~~~~~~
4//
b32b8144 5// Copyright (c) 2003-2017 Christopher M. Kohlhoff (chris at kohlhoff dot com)
7c673cae
FG
6//
7// Distributed under the Boost Software License, Version 1.0. (See accompanying
8// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
9//
10
11#ifndef ICMP_HEADER_HPP
12#define ICMP_HEADER_HPP
13
14#include <istream>
15#include <ostream>
16#include <algorithm>
17
18// ICMP header for both IPv4 and IPv6.
19//
20// The wire format of an ICMP header is:
21//
22// 0 8 16 31
23// +---------------+---------------+------------------------------+ ---
24// | | | | ^
25// | type | code | checksum | |
26// | | | | |
27// +---------------+---------------+------------------------------+ 8 bytes
28// | | | |
29// | identifier | sequence number | |
30// | | | v
31// +-------------------------------+------------------------------+ ---
32
33class icmp_header
34{
35public:
36 enum { echo_reply = 0, destination_unreachable = 3, source_quench = 4,
37 redirect = 5, echo_request = 8, time_exceeded = 11, parameter_problem = 12,
38 timestamp_request = 13, timestamp_reply = 14, info_request = 15,
39 info_reply = 16, address_request = 17, address_reply = 18 };
40
41 icmp_header() { std::fill(rep_, rep_ + sizeof(rep_), 0); }
42
43 unsigned char type() const { return rep_[0]; }
44 unsigned char code() const { return rep_[1]; }
45 unsigned short checksum() const { return decode(2, 3); }
46 unsigned short identifier() const { return decode(4, 5); }
47 unsigned short sequence_number() const { return decode(6, 7); }
48
49 void type(unsigned char n) { rep_[0] = n; }
50 void code(unsigned char n) { rep_[1] = n; }
51 void checksum(unsigned short n) { encode(2, 3, n); }
52 void identifier(unsigned short n) { encode(4, 5, n); }
53 void sequence_number(unsigned short n) { encode(6, 7, n); }
54
55 friend std::istream& operator>>(std::istream& is, icmp_header& header)
56 { return is.read(reinterpret_cast<char*>(header.rep_), 8); }
57
58 friend std::ostream& operator<<(std::ostream& os, const icmp_header& header)
59 { return os.write(reinterpret_cast<const char*>(header.rep_), 8); }
60
61private:
62 unsigned short decode(int a, int b) const
63 { return (rep_[a] << 8) + rep_[b]; }
64
65 void encode(int a, int b, unsigned short n)
66 {
67 rep_[a] = static_cast<unsigned char>(n >> 8);
68 rep_[b] = static_cast<unsigned char>(n & 0xFF);
69 }
70
71 unsigned char rep_[8];
72};
73
74template <typename Iterator>
75void compute_checksum(icmp_header& header,
76 Iterator body_begin, Iterator body_end)
77{
78 unsigned int sum = (header.type() << 8) + header.code()
79 + header.identifier() + header.sequence_number();
80
81 Iterator body_iter = body_begin;
82 while (body_iter != body_end)
83 {
84 sum += (static_cast<unsigned char>(*body_iter++) << 8);
85 if (body_iter != body_end)
86 sum += static_cast<unsigned char>(*body_iter++);
87 }
88
89 sum = (sum >> 16) + (sum & 0xFFFF);
90 sum += (sum >> 16);
91 header.checksum(static_cast<unsigned short>(~sum));
92}
93
94#endif // ICMP_HEADER_HPP