| 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 |