Commit | Line | Data |
---|---|---|
39d326f2 CH |
1 | /* |
2 | The software in this package is distributed under the GNU General | |
3 | Public License version 2 (with a special exception described below). | |
4 | ||
5 | A copy of GNU General Public License (GPL) is included in this distribution, | |
6 | in the file COPYING.GPL. | |
7 | ||
8 | As a special exception, if other files instantiate templates or use macros | |
9 | or inline functions from this file, or you compile this file and link it | |
10 | with other works to produce a work based on this file, this file | |
11 | does not by itself cause the resulting work to be covered | |
12 | by the GNU General Public License. | |
13 | ||
14 | However the source code for this file must still be made available | |
15 | in accordance with section (3) of the GNU General Public License. | |
16 | ||
17 | This exception does not invalidate any other reasons why a work based | |
18 | on this file might be covered by the GNU General Public License. | |
19 | ||
20 | Christian Herdtweck, Intra2net AG 2015 | |
057e6cc9 CH |
21 | Based on an example in Boost Documentation (by Christopher M. Kohlhoff) |
22 | and adaptation by Guilherme M. Ferreira | |
39d326f2 CH |
23 | */ |
24 | ||
25 | #include "icmp/icmpheader.h" | |
8f07c5f0 | 26 | #include <sstream> |
39d326f2 CH |
27 | #include <boost/scoped_array.hpp> |
28 | ||
0ba8adc0 CH |
29 | IcmpHeader::IcmpHeader() |
30 | : type( 0 ) | |
31 | , code( 0 ) | |
32 | , checksum( 0 ) | |
33 | {} | |
34 | ||
35 | IcmpHeader::IcmpHeader(const uint8_t type_arg, const uint8_t code_arg) | |
36 | : type( type_arg ) | |
37 | , code( code_arg ) | |
38 | , checksum( 0 ) | |
39 | {} | |
40 | ||
41 | uint16_t IcmpHeader::get_header_length() const { return 4; } | |
42 | uint8_t IcmpHeader::get_type() const { return type; } | |
43 | uint8_t IcmpHeader::get_code() const { return code; } | |
44 | uint16_t IcmpHeader::get_checksum() const { return checksum; } | |
45 | ||
46 | ||
39d326f2 CH |
47 | std::istream& IcmpHeader::read(std::istream &is) |
48 | { | |
49 | boost::scoped_array<char> buf( new char[4] ); | |
50 | is.read(buf.get(), 4); | |
51 | type = static_cast<uint8_t>(buf[0]); | |
52 | code = static_cast<uint8_t>(buf[1]); | |
fc921308 CH |
53 | |
54 | // first make the 2 checksum byte unsigned with same size | |
8f07c5f0 CH |
55 | uint8_t checksum_msb = static_cast<uint8_t>(buf[2]); |
56 | uint8_t checksum_lsb = static_cast<uint8_t>(buf[3]); | |
fc921308 CH |
57 | |
58 | // now extend type, shift and add/or them | |
59 | checksum = static_cast<uint16_t>( | |
60 | (static_cast<uint16_t>(checksum_msb) << 8) | |
61 | | static_cast<uint16_t>(checksum_lsb) ); | |
62 | // need the static_cast around the result since compiler casts everything | |
63 | // to int before doing | or + if types are smaller than int | |
39d326f2 CH |
64 | |
65 | return is; | |
66 | } | |
67 | ||
68 | std::ostream& IcmpHeader::write(std::ostream &os) const | |
69 | { | |
70 | uint8_t checksum_lsb = static_cast<uint8_t>(checksum & 0x00FF); | |
71 | uint8_t checksum_msb = static_cast<uint8_t>((checksum & 0xFF00) >> 8); | |
72 | return os << type << code << checksum_msb << checksum_lsb; | |
73 | } | |
74 | ||
75 | ||
76 | // code adapted from boost icmp example by Christopher M. Kohlhoff | |
77 | // --> boost license?!? | |
78 | void IcmpHeader::calc_checksum( const uint32_t body_checksum_part ) | |
79 | { | |
80 | uint32_t sum = (type << 8) + code; | |
81 | sum += body_checksum_part; | |
82 | ||
83 | sum = (sum >> 16) + (sum & 0xFFFF); | |
84 | sum += (sum >> 16); | |
85 | ||
86 | checksum = static_cast<uint16_t>( ~sum ); | |
87 | } | |
88 | ||
89 | ||
90 | std::string IcmpHeader::to_string() const | |
91 | { | |
92 | std::stringstream buf; | |
93 | buf << "[Icmp header type=" << static_cast<int>(type) | |
94 | << ",code=" << static_cast<int>(code) | |
15023b99 CH |
95 | // << " (cksum:" << std::showbase << std::hex << checksum << ")" |
96 | << "]"; | |
39d326f2 CH |
97 | return buf.str(); |
98 | } | |
99 | ||
100 | ||
101 | std::istream& operator>>( | |
102 | std::istream &is, | |
103 | IcmpHeader &header | |
104 | ) | |
105 | { return header.read( is ); } | |
106 | ||
107 | std::ostream& operator<<( | |
108 | std::ostream &os, | |
109 | const IcmpHeader &header | |
110 | ) | |
111 | { return header.write( os ); } | |
112 |