]>
Commit | Line | Data |
---|---|---|
7c673cae FG |
1 | // |
2 | // ipv4_header.hpp | |
3 | // ~~~~~~~~~~~~~~~ | |
4 | // | |
f51cf556 | 5 | // Copyright (c) 2003-2023 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 | ||
51 | class ipv4_header | |
52 | { | |
53 | public: | |
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 | ||
95 | private: | |
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 |