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 "icmpdata.h" | |
26 | ||
27 | #include <sstream> | |
81c26517 CH |
28 | #include <iostream> |
29 | ||
30 | #include <logfunc.hpp> | |
31 | ||
32 | #include "boost_assert_handler.h" | |
33 | #include "ip/ipv4header.h" | |
34 | #include "ip/ipv6header.h" | |
35 | ||
36 | using I2n::Logger::GlobalLogger; | |
37 | using boost::asio::ip::address; | |
39d326f2 | 38 | |
0ba8adc0 CH |
39 | IcmpData::IcmpData() |
40 | : size( 0 ) | |
41 | , raw_data( 0 ) | |
42 | {} | |
43 | ||
44 | IcmpData::IcmpData(const std::size_t size_arg) | |
45 | : size( size_arg ) | |
46 | , raw_data( size_arg ) | |
47 | {} | |
48 | ||
49 | bool IcmpData::match_echo_reply(const uint16_t identifier, | |
50 | const uint16_t sequence_number) const | |
fc921308 | 51 | { return false; } |
0ba8adc0 CH |
52 | |
53 | bool IcmpData::match_destination_unreachable(const uint16_t identifier, | |
81c26517 CH |
54 | const uint16_t sequence_number, |
55 | const address &destination_address) const | |
15023b99 CH |
56 | { return false; } |
57 | ||
58 | bool IcmpData::match_time_exceeded(const uint16_t identifier, | |
24fdf496 CH |
59 | const uint16_t sequence_number, |
60 | const address &destination_address) const | |
fc921308 | 61 | { return false; } |
0ba8adc0 | 62 | |
aadc7032 | 63 | std::size_t IcmpData::get_size() const |
fc921308 | 64 | { return size; } |
0ba8adc0 | 65 | |
aadc7032 CH |
66 | int IcmpData::get_ip_version() const |
67 | { | |
68 | int offset = 4; // the 4 uninteresting bytes we need to skip | |
69 | uint8_t version_with_ihl = static_cast<uint8_t>(IcmpData::raw_data[offset]); | |
70 | int version = static_cast<int>( (version_with_ihl & 0xF0) >> 4 ); | |
71 | return version; | |
72 | } | |
73 | ||
81c26517 CH |
74 | IpHeaderPtr IcmpData::get_ip_header() const |
75 | { | |
76 | // make stream from relevant part of payload | |
77 | std::stringbuf buffer; | |
78 | std::ostream buf_filler( &buffer ); | |
79 | raw_data.write( buf_filler ); | |
80 | std::istream stream( &buffer ); | |
81 | ||
82 | // skip 4 byte | |
83 | stream.seekg(4, stream.beg); | |
84 | ||
85 | // interpret as IP header | |
86 | int ip_version = get_ip_version(); | |
87 | IpHeaderPtr result; | |
88 | if (ip_version == 4) | |
89 | { | |
90 | Ipv4Header *result_val = new Ipv4Header(); | |
91 | stream >> *result_val; | |
92 | result.reset( result_val ); | |
93 | } | |
94 | else if (ip_version == 6) | |
95 | { | |
96 | Ipv6Header *result_val = new Ipv6Header(); | |
97 | stream >> *result_val; | |
98 | result.reset( result_val ); | |
99 | } | |
100 | else | |
101 | { // throw runtime error through boost_assert_handler | |
102 | GlobalLogger.error() << "Invalid IP version: " << ip_version | |
103 | << " ! Maybe data is no IP packet?"; | |
104 | BOOST_ASSERT( !"Invalid IP version or not IP packet!" ); | |
105 | } | |
106 | ||
107 | return result; | |
108 | } | |
109 | ||
0ba8adc0 CH |
110 | uint32_t IcmpData::calc_checksum_part() const |
111 | { return raw_data.calc_checksum_part(); } | |
112 | ||
113 | ||
114 | void IcmpData::print( const size_t &bytes_received, | |
115 | const boost::posix_time::ptime &time_packet_sent, | |
116 | const std::string &remote_address, | |
117 | const uint32_t ttl) const | |
118 | {} | |
119 | ||
39d326f2 CH |
120 | std::istream& IcmpData::read(std::istream &is) // read raw data |
121 | { | |
122 | return raw_data.read(is); | |
123 | } | |
124 | ||
125 | std::ostream& IcmpData::write(std::ostream &os) const | |
126 | { | |
127 | return raw_data.write(os); | |
128 | } | |
129 | ||
130 | std::string IcmpData::to_string() const | |
131 | { | |
132 | std::stringstream buf; | |
133 | buf << "[IcmpData of length " << size << "]"; | |
134 | return buf.str(); | |
135 | } | |
136 | ||
137 | std::istream& operator>>( | |
138 | std::istream &is, | |
139 | IcmpData &data | |
140 | ) | |
141 | { return data.read( is ); } | |
142 | ||
143 | std::ostream& operator<<( | |
144 | std::ostream &os, | |
145 | const IcmpData &data | |
146 | ) | |
147 | { return data.write( os ); } | |
148 |