libtins 4.5
Loading...
Searching...
No Matches
icmp.h
1/*
2 * Copyright (c) 2017, Matias Fontanini
3 * All rights reserved.
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions are
7 * met:
8 *
9 * * Redistributions of source code must retain the above copyright
10 * notice, this list of conditions and the following disclaimer.
11 * * Redistributions in binary form must reproduce the above
12 * copyright notice, this list of conditions and the following disclaimer
13 * in the documentation and/or other materials provided with the
14 * distribution.
15 *
16 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
17 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
18 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
19 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
20 * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
21 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
22 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
23 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
24 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
25 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
26 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
27 *
28 */
29
30#ifndef TINS_ICMP_H
31#define TINS_ICMP_H
32
33// Windows likes to define macros with not-so-common-names, which break
34// this code
35#ifdef _WIN32
36 #ifdef TIMESTAMP_REQUEST
37 #undef TIMESTAMP_REQUEST
38 #endif // TIMESTAMP_REQUEST
39
40 #ifdef TIMESTAMP_REPLY
41 #undef TIMESTAMP_REPLY
42 #endif // TIMESTAMP_REPLY
43#endif // _WIN32
44
45#include <tins/macros.h>
46#include <tins/pdu.h>
47#include <tins/endianness.h>
48#include <tins/ip_address.h>
49#include <tins/icmp_extension.h>
50
51namespace Tins {
52namespace Memory {
53
54class InputMemoryStream;
55
56} // Memory
57
65class TINS_API ICMP : public PDU {
66public:
70 static const PDU::PDUType pdu_flag = PDU::ICMP;
71
76
79 enum Flags {
80 ECHO_REPLY = 0,
81 DEST_UNREACHABLE = 3,
82 SOURCE_QUENCH = 4,
83 REDIRECT = 5,
84 ECHO_REQUEST = 8,
85 TIME_EXCEEDED = 11,
86 PARAM_PROBLEM = 12,
87 TIMESTAMP_REQUEST = 13,
88 TIMESTAMP_REPLY = 14,
89 INFO_REQUEST = 15,
90 INFO_REPLY = 16,
91 ADDRESS_MASK_REQUEST = 17,
92 ADDRESS_MASK_REPLY = 18,
93 EXTENDED_ECHO_REQUEST = 42,
94 EXTENDED_ECHO_REPLY = 43
95 };
96
103 static metadata extract_metadata(const uint8_t *buffer, uint32_t total_sz);
104
111 ICMP(Flags flag = ECHO_REQUEST);
112
124 ICMP(const uint8_t* buffer, uint32_t total_sz);
125
131 void code(uint8_t new_code);
132
137 void type(Flags type);
138
144 void id(uint16_t new_id);
145
151 void sequence(uint16_t new_seq);
152
158 void gateway(address_type new_gw);
159
165 void mtu(uint16_t new_mtu);
166
172 void pointer(uint8_t new_pointer);
173
179 void original_timestamp(uint32_t new_timestamp);
180
186 void receive_timestamp(uint32_t new_timestamp);
187
193 void transmit_timestamp(uint32_t new_timestamp);
194
200 void address_mask(address_type new_mask);
201
208 void set_echo_request(uint16_t id, uint16_t seq);
209
216 void set_echo_reply(uint16_t id, uint16_t seq);
217
224 void set_info_request(uint16_t id, uint16_t seq);
225
232 void set_info_reply(uint16_t id, uint16_t seq);
233
237 void set_dest_unreachable();
238
246 void set_time_exceeded(bool ttl_exceeded = true);
247
256 void set_param_problem(bool set_pointer = false, uint8_t bad_octet = 0);
257
261 void set_source_quench();
262
270 void set_redirect(uint8_t icode, address_type address);
271
277 Flags type() const {
278 return (Flags)header_.type;
279 }
280
286 uint8_t code() const {
287 return header_.code;
288 }
289
295 uint16_t checksum() const {
296 return Endian::be_to_host(header_.check);
297 }
298
304 uint16_t id() const {
305 return Endian::be_to_host(header_.un.echo.id);
306 }
307
313 uint16_t sequence() const {
314 return Endian::be_to_host(header_.un.echo.sequence);
315 }
316
323 return address_type(header_.un.gateway);
324 }
325
331 uint8_t pointer() const {
332 return header_.un.rfc4884.pointer;
333 }
334
340 uint8_t length() const {
341 return header_.un.rfc4884.length;
342 }
343
349 uint16_t mtu() const {
350 return Endian::be_to_host(header_.un.frag.mtu);
351 }
352
358 uint32_t original_timestamp() const {
359 return Endian::be_to_host(orig_timestamp_or_address_mask_);
360 }
361
367 uint32_t receive_timestamp() const {
368 return Endian::be_to_host(recv_timestamp_);
369 }
370
376 uint32_t transmit_timestamp() const {
377 return Endian::be_to_host(trans_timestamp_);
378 }
379
386 return address_type(orig_timestamp_or_address_mask_);
387 }
388
397 uint32_t header_size() const;
398
406 uint32_t trailer_size() const;
407
415 bool matches_response(const uint8_t* ptr, uint32_t total_sz) const;
416
423 return extensions_;
424 }
425
432 return extensions_;
433 }
434
438 bool has_extensions() const {
439 return !extensions_.extensions().empty();
440 }
441
457 void use_length_field(bool value);
458
465 return pdu_flag;
466 }
467
471 ICMP* clone() const {
472 return new ICMP(*this);
473 }
474private:
475 TINS_BEGIN_PACK
476 struct icmp_header {
477 uint8_t type;
478 uint8_t code;
479 uint16_t check;
480 union {
481 struct {
482 uint16_t id;
483 uint16_t sequence;
484 } echo;
485 uint32_t gateway;
486 struct {
487 uint16_t unused;
488 uint16_t mtu;
489 } frag;
490 struct {
491 uint8_t pointer;
492 uint8_t length;
493 uint16_t unused;
494 } rfc4884;
495 } un;
496 } TINS_END_PACK;
497
498 void checksum(uint16_t new_check);
499 void write_serialization(uint8_t* buffer, uint32_t total_sz);
500 uint32_t get_adjusted_inner_pdu_size() const;
501 void try_parse_extensions(Memory::InputMemoryStream& stream);
502 bool are_extensions_allowed() const;
503
504 icmp_header header_;
505 uint32_t orig_timestamp_or_address_mask_;
506 uint32_t recv_timestamp_;
507 uint32_t trans_timestamp_;
508 ICMPExtensionsStructure extensions_;
509};
510
511} // Tins
512
513#endif // TINS_ICMP_H
Class that represents an ICMP extensions structure.
Definition icmp_extension.h:161
Class that represents an ICMP PDU.
Definition icmp.h:65
uint16_t id() const
Getter for the echo id.
Definition icmp.h:304
uint16_t sequence() const
Getter for the echo sequence number.
Definition icmp.h:313
uint16_t mtu() const
Getter for the mtu field.
Definition icmp.h:349
uint32_t receive_timestamp() const
Getter for the receive timestamp field.
Definition icmp.h:367
uint8_t length() const
Getter for the length field.
Definition icmp.h:340
IPv4Address address_type
Definition icmp.h:75
const ICMPExtensionsStructure & extensions() const
Getter for the extensions field.
Definition icmp.h:422
uint32_t transmit_timestamp() const
Getter for the transmit timestamp field.
Definition icmp.h:376
uint16_t checksum() const
Getter for the checksum field.
Definition icmp.h:295
bool has_extensions() const
Indicates whether this object contains ICMP extensions.
Definition icmp.h:438
uint8_t pointer() const
Getter for the pointer field.
Definition icmp.h:331
Flags type() const
Getter for the ICMP type flag.
Definition icmp.h:277
uint8_t code() const
Getter for the ICMP code flag.
Definition icmp.h:286
address_type address_mask() const
Getter for the address mask field.
Definition icmp.h:385
address_type gateway() const
Getter for the gateway field.
Definition icmp.h:322
PDUType pdu_type() const
Getter for the PDU's type.
Definition icmp.h:464
Flags
ICMP flags.
Definition icmp.h:79
uint32_t original_timestamp() const
Getter for the original timestamp field.
Definition icmp.h:358
ICMPExtensionsStructure & extensions()
Getter for the extensions field.
Definition icmp.h:431
ICMP * clone() const
Definition icmp.h:471
Abstraction of an IPv4 address.
Definition ip_address.h:45
Base class for protocol data units.
Definition pdu.h:107
PDUType
Enum which identifies each type of PDU.
Definition pdu.h:127
The Tins namespace.
Definition address_range.h:38