libtins 4.5
Loading...
Searching...
No Matches
ip.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_IP_H
31#define TINS_IP_H
32
33#include <tins/pdu.h>
34#include <tins/small_uint.h>
35#include <tins/endianness.h>
36#include <tins/ip_address.h>
37#include <tins/pdu_option.h>
38#include <tins/macros.h>
39#include <tins/cxxstd.h>
40
41namespace Tins {
42namespace Memory {
43
44class OutputMemoryStream;
45
46} // Memory
47
63class TINS_API IP : public PDU {
64public:
68 static const PDU::PDUType pdu_flag = PDU::IP;
69
74
78 enum Flags {
79 FLAG_RESERVED = 4,
80 DONT_FRAGMENT = 2,
81 MORE_FRAGMENTS = 1
82 };
83
91 CONTROL = 0,
92 MEASUREMENT = 2
93 };
94
101 END = 0,
102 NOOP = 1,
103 SEC = 2,
104 LSRR = 3,
105 TIMESTAMP = 4,
106 EXTSEC = 5,
107 RR = 7,
108 SID = 8,
109 SSRR = 9,
110 MTUPROBE = 11,
111 MTUREPLY = 12,
112 EIP = 17,
113 TR = 18,
114 ADDEXT = 19,
115 RTRALT = 20,
116 SDB = 21,
117 DPS = 23,
118 UMP = 24,
119 QS = 25
120 };
121
125 TINS_BEGIN_PACK
127 #if TINS_IS_LITTLE_ENDIAN
128 uint8_t number:5,
129 op_class:2,
130 copied:1;
131 #elif TINS_IS_BIG_ENDIAN
132 uint8_t copied:1,
133 op_class:2,
134 number:5;
135 #endif
142 #if TINS_IS_LITTLE_ENDIAN
143 : number(0), op_class(0), copied(0) {}
144 #else
145 : copied(0), op_class(0), number(0) {}
146 #endif
147
157 option_identifier(uint8_t value)
158 #if TINS_IS_LITTLE_ENDIAN
159 : number(value & 0x1f),
160 op_class((value >> 5) & 0x03),
161 copied((value >> 7) & 0x01) {}
162 #elif TINS_IS_BIG_ENDIAN
163 : copied((value >> 7) & 0x01),
164 op_class((value >> 5) & 0x03),
165 number(value & 0x1f) {}
166 #endif
167
174 option_identifier(OptionNumber number, OptionClass op_class,
175 small_uint<1> copied)
176 #if TINS_IS_LITTLE_ENDIAN
177 : number(static_cast<uint8_t>(number)), op_class(static_cast<uint8_t>(op_class)), copied(copied) {}
178 #else
179 : copied(copied), op_class(static_cast<uint8_t>(op_class)), number(static_cast<uint8_t>(number)) {}
180 #endif
181
185 bool operator==(const option_identifier& rhs) const {
186 return number == rhs.number && op_class == rhs.op_class && copied == rhs.copied;
187 }
188 } TINS_END_PACK;
189
194
199 uint16_t security, compartments;
200 uint16_t handling_restrictions;
201 small_uint<24> transmission_control;
202
203 security_type(uint16_t sec = 0,
204 uint16_t comp = 0,
205 uint16_t hand_res = 0,
206 small_uint<24> tcc = 0)
207 : security(sec), compartments(comp),
208 handling_restrictions(hand_res), transmission_control(tcc) { }
209
210 static security_type from_option(const option& opt);
211 };
212
217 typedef std::vector<address_type> routes_type;
218
219 uint8_t pointer;
220 routes_type routes;
221
222 generic_route_option_type(uint8_t ptr = 0, routes_type rts = routes_type())
223 : pointer(ptr), routes(rts) {}
224
225 static generic_route_option_type from_option(const option& opt);
226 };
227
232
237
242
246 typedef std::vector<option> options_type;
247
254 static metadata extract_metadata(const uint8_t *buffer, uint32_t total_sz);
255
266 IP(address_type ip_dst = address_type(),
267 address_type ip_src = address_type());
268
280 IP(const uint8_t* buffer, uint32_t total_sz);
281
282 /* Getters */
283
284 uint32_t advertised_size() const {
285 return static_cast<uint32_t>(tot_len());
286 }
287
294 return this->header_.ihl;
295 }
296
302 uint8_t tos() const {
303 return header_.tos;
304 }
305
311 uint16_t tot_len() const {
312 return Endian::be_to_host(header_.tot_len);
313 }
314
320 uint16_t id() const {
321 return Endian::be_to_host(header_.id);
322 }
323
334 TINS_DEPRECATED(uint16_t frag_off() const) {
335 return Endian::be_to_host(header_.frag_off);
336 }
337
347 return Endian::be_to_host(header_.frag_off) & 0x1fff;
348 }
349
355 Flags flags() const {
356 return static_cast<Flags>(Endian::be_to_host(header_.frag_off) >> 13);
357 }
358
364 uint8_t ttl() const {
365 return header_.ttl;
366 }
367
373 uint8_t protocol() const {
374 return header_.protocol;
375 }
376
382 uint16_t checksum() const {
383 return Endian::be_to_host(header_.check);
384 }
385
392 return address_type(header_.saddr);
393 }
394
400 return address_type(header_.daddr);
401 }
402
408 return header_.version;
409 }
410
415 const options_type& options() const {
416 return options_;
417 }
418
419 /* Setters */
420
426 void tos(uint8_t new_tos);
427
433 void id(uint16_t new_id);
434
445 TINS_DEPRECATED(void frag_off(uint16_t new_frag_off));
446
456 void fragment_offset(small_uint<13> new_frag_off);
457
463 void flags(Flags new_flags);
464
470 void ttl(uint8_t new_ttl);
471
488 void protocol(uint8_t new_protocol);
489
495 void src_addr(address_type ip);
496
502 void dst_addr(address_type ip);
503
509 void version(small_uint<4> ver);
510
519 void add_option(const option& opt);
520
521 #if TINS_IS_CXX11
529 void add_option(option &&opt) {
530 options_.push_back(std::move(opt));
531 }
532
541 template<typename... Args>
542 void add_option(Args&&... args) {
543 options_.emplace_back(std::forward<Args>(args)...);
544 }
545 #endif
546
556 bool remove_option(option_identifier id);
557
567 const option* search_option(option_identifier id) const;
568
569 // Option setters
570
574 void eol();
575
579 void noop();
580
586 void security(const security_type& data);
587
593 void lsrr(const lsrr_type& data) {
594 add_route_option(131, data);
595 }
596
602 void ssrr(const ssrr_type& data) {
603 add_route_option(137, data);
604 }
605
611 void record_route(const record_route_type& data) {
612 add_route_option(7, data);
613 }
614
620 void stream_identifier(uint16_t stream_id);
621
622 // Option getters
623
632 security_type security() const;
633
643 lsrr_type lsrr() const {
644 return search_route_option(131);
645 }
646
656 ssrr_type ssrr() const {
657 return search_route_option(137);
658 }
659
669 return search_route_option(7);
670 }
671
680 uint16_t stream_identifier() const;
681
682 /* Virtual methods */
683
689 uint32_t header_size() const;
690
694 void send(PacketSender& sender, const NetworkInterface &);
695
703 bool matches_response(const uint8_t* ptr, uint32_t total_sz) const;
704
711 PDU* recv_response(PacketSender& sender, const NetworkInterface &);
712
718 bool is_fragmented() const;
719
725 return pdu_flag;
726 }
727
731 IP* clone() const {
732 return new IP(*this);
733 }
734private:
735 static const uint8_t DEFAULT_TTL;
736
737 TINS_BEGIN_PACK
738 struct ip_header {
739 #if TINS_IS_LITTLE_ENDIAN
740 uint8_t ihl:4,
741 version:4;
742 #else
743 uint8_t version:4,
744 ihl:4;
745 #endif
746 uint8_t tos;
747 uint16_t tot_len;
748 uint16_t id;
749 uint16_t frag_off;
750 uint8_t ttl;
751 uint8_t protocol;
752 uint16_t check;
753 uint32_t saddr;
754 uint32_t daddr;
755 } TINS_END_PACK;
756
757 void head_len(small_uint<4> new_head_len);
758 void tot_len(uint16_t new_tot_len);
759
760 void prepare_for_serialize();
761 uint32_t calculate_options_size() const;
762 uint32_t pad_options_size(uint32_t size) const;
763 void init_ip_fields();
764 void write_serialization(uint8_t* buffer, uint32_t total_sz);
765 void write_option(const option& opt, Memory::OutputMemoryStream& stream);
766 void add_route_option(option_identifier id, const generic_route_option_type& data);
767 generic_route_option_type search_route_option(option_identifier id) const;
768 void checksum(uint16_t new_check);
769 options_type::const_iterator search_option_iterator(option_identifier id) const;
770 options_type::iterator search_option_iterator(option_identifier id);
771
772 options_type options_;
773 ip_header header_;
774};
775
776} // Tins
777
778#endif // TINS_IP_H
Class that represents an IP PDU.
Definition ip.h:63
TINS_DEPRECATED(uint16_t frag_off() const)
Getter for the fragment offset field.
Definition ip.h:334
uint16_t tot_len() const
Getter for the total length field.
Definition ip.h:311
OptionClass
Enum indicating the option's class.
Definition ip.h:90
generic_route_option_type record_route_type
Definition ip.h:241
uint16_t checksum() const
Getter for the checksum field.
Definition ip.h:382
uint8_t protocol() const
Getter for the protocol field.
Definition ip.h:373
IPv4Address address_type
Definition ip.h:73
Flags
Definition ip.h:78
uint8_t tos() const
Getter for the type of service field.
Definition ip.h:302
std::vector< option > options_type
Definition ip.h:246
PDUType pdu_type() const
Getter for the PDU's type.
Definition ip.h:724
ssrr_type ssrr() const
Searchs and returns a Strict Source and Record Route option.
Definition ip.h:656
lsrr_type lsrr() const
Searchs and returns a Loose Source and Record Route option.
Definition ip.h:643
address_type src_addr() const
Getter for the source address field.
Definition ip.h:391
IP * clone() const
Definition ip.h:731
void ssrr(const ssrr_type &data)
Adds a Strict Source and Record Route option.
Definition ip.h:602
small_uint< 4 > head_len() const
Getter for the header length field.
Definition ip.h:293
PDUOption< option_identifier, IP > option
Definition ip.h:193
void add_option(Args &&... args)
Adds an IP option.
Definition ip.h:542
address_type dst_addr() const
Getter for the destination address field.
Definition ip.h:399
Flags flags() const
Getter for the flags field.
Definition ip.h:355
generic_route_option_type lsrr_type
Definition ip.h:231
small_uint< 13 > fragment_offset() const
Getter for the fragment offset field.
Definition ip.h:346
generic_route_option_type ssrr_type
Definition ip.h:236
TINS_DEPRECATED(void frag_off(uint16_t new_frag_off))
Setter for the fragment offset field.
void lsrr(const lsrr_type &data)
Adds a Loose Source and Record Route option.
Definition ip.h:593
OptionNumber
Enum indicating the option's id number.
Definition ip.h:100
uint8_t ttl() const
Getter for the time to live field.
Definition ip.h:364
record_route_type record_route() const
Searchs and returns a Record Route option.
Definition ip.h:668
void record_route(const record_route_type &data)
Adds a Record Route option.
Definition ip.h:611
uint32_t advertised_size() const
The whole chain of PDU's advertised size, including this one.
Definition ip.h:284
uint16_t id() const
Getter for the id field.
Definition ip.h:320
const options_type & options() const
Getter for the IP options.
Definition ip.h:415
small_uint< 4 > version() const
Getter for the version field.
Definition ip.h:407
void add_option(option &&opt)
Adds an IP option.
Definition ip.h:529
Abstraction of an IPv4 address.
Definition ip_address.h:45
Abstraction of a network interface.
Definition network_interface.h:47
Represents a PDU option field.
Definition rsn_information.h:43
Base class for protocol data units.
Definition pdu.h:107
PDUType
Enum which identifies each type of PDU.
Definition pdu.h:127
Sends packets through a network interface.
Definition packet_sender.h:118
Represents a field of n bits.
Definition small_uint.h:52
The Tins namespace.
Definition address_range.h:38
The type used to represent an option's type.
Definition ip.h:126
option_identifier(uint8_t value) option_identifier(OptionNumber number
Constructs this option from a single uint8_t value.
option_identifier()
Default constructor.
Definition ip.h:141
bool operator==(const option_identifier &rhs) const
Equality operator.
Definition ip.h:185
Definition ip.h:198
Type used to store a PDU header's data.
Definition pdu.h:197