src/​examples/​cpp03/​icmp/​icmp_header.​hppsrc/​examples/​cpp11/​icmp/​icmp_header.​hpp
1 /​/​1 /​/​
2 /​/​·​icmp_header.​hpp2 /​/​·​icmp_header.​hpp
3 /​/​·​~~~~~~~~~~~~~~~3 /​/​·​~~~~~~~~~~~~~~~
4 /​/​4 /​/​
5 /​/​·​Copyright·​(c)​·​2003-​2018·​Christopher·​M.​·​Kohlhoff·​(chris·​at·​kohlhoff·​dot·​com)​5 /​/​·​Copyright·​(c)​·​2003-​2018·​Christopher·​M.​·​Kohlhoff·​(chris·​at·​kohlhoff·​dot·​com)​
6 /​/​6 /​/​
7 /​/​·​Distributed·​under·​the·​Boost·​Software·​License,​·​Version·​1.​0.​·​(See·​accompanying7 /​/​·​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_HPP11 #ifndef·​ICMP_HEADER_HPP
12 #define·​ICMP_HEADER_HPP12 #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·····························​3118 /​/​·​0···············​8···············​16·····························​31
23 /​/​·​+-​-​-​-​-​-​-​-​-​-​-​-​-​-​-​+-​-​-​-​-​-​-​-​-​-​-​-​-​-​-​+-​-​-​-​-​-​-​-​-​-​-​-​-​-​-​-​-​-​-​-​-​-​-​-​-​-​-​-​-​-​+······​-​-​-​19 /​/​·​+-​-​-​-​-​-​-​-​-​-​-​-​-​-​-​+-​-​-​-​-​-​-​-​-​-​-​-​-​-​-​+-​-​-​-​-​-​-​-​-​-​-​-​-​-​-​-​-​-​-​-​-​-​-​-​-​-​-​-​-​-​+······​-​-​-​
24 /​/​·​|···············​|···············​|······························​|·······​^20 /​/​·​|···············​|···············​|······························​|·······​^
25 /​/​·​|·····​type······​|·····​code······​|··········​checksum············​|·······​|21 /​/​·​|·····​type······​|·····​code······​|··········​checksum············​|·······​|
26 /​/​·​|···············​|···············​|······························​|·······​|22 /​/​·​|···············​|···············​|······························​|·······​|
27 /​/​·​+-​-​-​-​-​-​-​-​-​-​-​-​-​-​-​+-​-​-​-​-​-​-​-​-​-​-​-​-​-​-​+-​-​-​-​-​-​-​-​-​-​-​-​-​-​-​-​-​-​-​-​-​-​-​-​-​-​-​-​-​-​+····​8·​bytes23 /​/​·​+-​-​-​-​-​-​-​-​-​-​-​-​-​-​-​+-​-​-​-​-​-​-​-​-​-​-​-​-​-​-​+-​-​-​-​-​-​-​-​-​-​-​-​-​-​-​-​-​-​-​-​-​-​-​-​-​-​-​-​-​-​+····​8·​bytes
28 /​/​·​|·······························​|······························​|·······​|24 /​/​·​|·······························​|······························​|·······​|
29 /​/​·​|··········​identifier···········​|·······​sequence·​number········​|·······​|25 /​/​·​|··········​identifier···········​|·······​sequence·​number········​|·······​|
30 /​/​·​|·······························​|······························​|·······​v26 /​/​·​|·······························​|······························​|·······​v
31 /​/​·​+-​-​-​-​-​-​-​-​-​-​-​-​-​-​-​-​-​-​-​-​-​-​-​-​-​-​-​-​-​-​-​+-​-​-​-​-​-​-​-​-​-​-​-​-​-​-​-​-​-​-​-​-​-​-​-​-​-​-​-​-​-​+······​-​-​-​27 /​/​·​+-​-​-​-​-​-​-​-​-​-​-​-​-​-​-​-​-​-​-​-​-​-​-​-​-​-​-​-​-​-​-​+-​-​-​-​-​-​-​-​-​-​-​-​-​-​-​-​-​-​-​-​-​-​-​-​-​-​-​-​-​-​+······​-​-​-​
32 28
33 class·​icmp_header29 class·​icmp_header
34 {30 {
35 public:​31 public:​
36 ··​enum·​{·​echo_reply·​=·​0,​·​destination_unreachab​le·​=·​3,​·​source_quench·​=·​4,​32 ··​enum·​{·​echo_reply·​=·​0,​·​destination_unreachab​le·​=·​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(unsig​ned·​short·​n)​·​{·​encode(6,​·​7,​·​n)​;​·​}47 ··​void·​sequence_number(unsig​ned·​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_cas​t<const·​char*>(header.​rep_)​,​·​8)​;​·​}
60
61 private:​49 private:​
62 ··​unsigned·​short·​decode(int·​a,​·​int·​b)​·​const50 ··​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_HPP82 #endif·​/​/​·​ICMP_HEADER_HPP