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