]> git.proxmox.com Git - ceph.git/blame - ceph/src/boost/libs/asio/example/cpp03/icmp/ipv4_header.hpp
update sources to v12.2.3
[ceph.git] / ceph / src / boost / libs / asio / example / cpp03 / icmp / ipv4_header.hpp
CommitLineData
7c673cae
FG
1//
2// ipv4_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 IPV4_HEADER_HPP
12#define IPV4_HEADER_HPP
13
14#include <algorithm>
15#include <boost/asio/ip/address_v4.hpp>
16
17// Packet header for IPv4.
18//
19// The wire format of an IPv4 header is:
20//
21// 0 8 16 31
22// +-------+-------+---------------+------------------------------+ ---
23// | | | | | ^
24// |version|header | type of | total length in bytes | |
25// | (4) | length| service | | |
26// +-------+-------+---------------+-+-+-+------------------------+ |
27// | | | | | | |
28// | identification |0|D|M| fragment offset | |
29// | | |F|F| | |
30// +---------------+---------------+-+-+-+------------------------+ |
31// | | | | |
32// | time to live | protocol | header checksum | 20 bytes
33// | | | | |
34// +---------------+---------------+------------------------------+ |
35// | | |
36// | source IPv4 address | |
37// | | |
38// +--------------------------------------------------------------+ |
39// | | |
40// | destination IPv4 address | |
41// | | v
42// +--------------------------------------------------------------+ ---
43// | | ^
44// | | |
45// / options (if any) / 0 - 40
46// / / bytes
47// | | |
48// | | v
49// +--------------------------------------------------------------+ ---
50
51class ipv4_header
52{
53public:
54 ipv4_header() { std::fill(rep_, rep_ + sizeof(rep_), 0); }
55
56 unsigned char version() const { return (rep_[0] >> 4) & 0xF; }
57 unsigned short header_length() const { return (rep_[0] & 0xF) * 4; }
58 unsigned char type_of_service() const { return rep_[1]; }
59 unsigned short total_length() const { return decode(2, 3); }
60 unsigned short identification() const { return decode(4, 5); }
61 bool dont_fragment() const { return (rep_[6] & 0x40) != 0; }
62 bool more_fragments() const { return (rep_[6] & 0x20) != 0; }
63 unsigned short fragment_offset() const { return decode(6, 7) & 0x1FFF; }
64 unsigned int time_to_live() const { return rep_[8]; }
65 unsigned char protocol() const { return rep_[9]; }
66 unsigned short header_checksum() const { return decode(10, 11); }
67
68 boost::asio::ip::address_v4 source_address() const
69 {
70 boost::asio::ip::address_v4::bytes_type bytes
71 = { { rep_[12], rep_[13], rep_[14], rep_[15] } };
72 return boost::asio::ip::address_v4(bytes);
73 }
74
75 boost::asio::ip::address_v4 destination_address() const
76 {
77 boost::asio::ip::address_v4::bytes_type bytes
78 = { { rep_[16], rep_[17], rep_[18], rep_[19] } };
79 return boost::asio::ip::address_v4(bytes);
80 }
81
82 friend std::istream& operator>>(std::istream& is, ipv4_header& header)
83 {
84 is.read(reinterpret_cast<char*>(header.rep_), 20);
85 if (header.version() != 4)
86 is.setstate(std::ios::failbit);
87 std::streamsize options_length = header.header_length() - 20;
88 if (options_length < 0 || options_length > 40)
89 is.setstate(std::ios::failbit);
90 else
91 is.read(reinterpret_cast<char*>(header.rep_) + 20, options_length);
92 return is;
93 }
94
95private:
96 unsigned short decode(int a, int b) const
97 { return (rep_[a] << 8) + rep_[b]; }
98
99 unsigned char rep_[60];
100};
101
102#endif // IPV4_HEADER_HPP