libtins 4.5
Loading...
Searching...
No Matches
ipv6.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_IPV6_h
31#define TINS_IPV6_h
32
33#include <tins/macros.h>
34#include <tins/cxxstd.h>
35#include <tins/pdu.h>
36#include <tins/endianness.h>
37#include <tins/small_uint.h>
38#include <tins/pdu_option.h>
39#include <tins/ipv6_address.h>
40
41namespace Tins {
42namespace Memory {
43
44class OutputMemoryStream;
45
46} // Memory
47
48class PacketSender;
49
54class TINS_API IPv6 : public PDU {
55public:
59 static const PDU::PDUType pdu_flag = PDU::IPv6;
60
65
70
74 typedef std::vector<ext_header> headers_type;
75
79 typedef std::pair<uint8_t, std::vector<uint8_t> > header_option_type;
80
85 HOP_BY_HOP = 0,
86 DESTINATION_ROUTING_OPTIONS = 60,
87 ROUTING = 43,
88 FRAGMENT = 44,
89 AUTHENTICATION = 51,
90 SECURITY_ENCAPSULATION = 50,
91 DESTINATION_OPTIONS = 60,
92 MOBILITY = 135,
93 NO_NEXT_HEADER = 59
94 };
95
100 PAD_1 = 0,
101 PAD_N = 1,
102 JUMBO_PAYLOAD = 0xC2,
103 };
104
111 static metadata extract_metadata(const uint8_t *buffer, uint32_t total_sz);
112
113 /*
114 * \brief The type used to store Hop-By-Hop Extension Headers
115 */
117 std::vector<header_option_type> options;
118
119 static hop_by_hop_header from_extension_header(const ext_header& hdr);
120 };
121
122 /*
123 * \brief The type used to store Destination Routing Extension Headers
124 */
126 std::vector<header_option_type> options;
127
128 static destination_routing_header from_extension_header(const ext_header& hdr);
129 };
130
135 uint8_t routing_type;
136 uint8_t segments_left;
137 std::vector<uint8_t> data;
138
139 static routing_header from_extension_header(const ext_header& hdr);
140 };
141
146 uint16_t fragment_offset;
147 bool more_fragments;
148 uint32_t identification;
149
150 static fragment_header from_extension_header(const ext_header& hdr);
151 };
152
161 IPv6(address_type ip_dst = address_type(),
162 address_type ip_src = address_type(),
163 PDU* child = 0);
164
175 IPv6(const uint8_t* buffer, uint32_t total_sz);
176
177 // Getters
178
184 return header_.version;
185 }
186
191 uint8_t traffic_class() const {
192 #if TINS_IS_LITTLE_ENDIAN
193 return ((header_.traffic_class << 4) & 0xf0) |
194 ((header_.flow_label[0] >> 4) & 0x0f);
195 #else
196 return header_.traffic_class;
197 #endif
198 }
199
205 #if TINS_IS_LITTLE_ENDIAN
206 return ((header_.flow_label[0] & 0x0f) << 16)
207 | (header_.flow_label[1] << 8)
208 | (header_.flow_label[2]);
209 #else
210 return header_.flow_label;
211 #endif
212 }
213
218 uint16_t payload_length() const {
219 return Endian::be_to_host(header_.payload_length);
220 }
221
226 uint8_t next_header() const {
227 return header_.next_header;
228 }
229
234 uint8_t hop_limit() const {
235 return header_.hop_limit;
236 }
237
243 return header_.src_addr;
244 }
245
251 return header_.dst_addr;
252 }
253
258 const headers_type& headers() const {
259 return ext_headers_;
260 }
261
262 // Setters
263
268 void version(small_uint<4> new_version);
269
274 void traffic_class(uint8_t new_traffic_class);
275
280 void flow_label(small_uint<20> new_flow_label);
281
286 void payload_length(uint16_t new_payload_length);
287
292 void next_header(uint8_t new_next_header);
293
298 void hop_limit(uint8_t new_hop_limit);
299
304 void src_addr(const address_type& new_src_addr);
305
310 void dst_addr(const address_type& new_dst_addr);
311
317 uint32_t header_size() const;
318
326 bool matches_response(const uint8_t* ptr, uint32_t total_sz) const;
327
331 IPv6* clone() const {
332 return new IPv6(*this);
333 }
334
339 PDUType pdu_type() const { return pdu_flag; }
340
341 #ifndef BSD
345 void send(PacketSender& sender, const NetworkInterface &);
346
353 PDU* recv_response(PacketSender& sender, const NetworkInterface &);
354 #endif
355
362 TINS_DEPRECATED(void add_ext_header(const ext_header& header));
363
370 void add_header(const ext_header& header);
371
372 #if TINS_IS_CXX11
373
379 void add_header(ext_header&& header) {
380 ext_headers_.emplace_back(std::move(header));
381 }
382
388 template <typename... Args>
389 void add_header(Args&&... args) {
390 ext_headers_.emplace_back(std::forward<Args>(args)...);
391 }
392
393 #endif // TINS_IS_CXX11
394
405 const ext_header* search_header(ExtensionHeader id) const;
406private:
407 void write_serialization(uint8_t* buffer, uint32_t total_sz);
408 void set_last_next_header(uint8_t value);
409 uint32_t calculate_headers_size() const;
410 static void write_header(const ext_header& header, Memory::OutputMemoryStream& stream);
411 static bool is_extension_header(uint8_t header_id);
412 static uint32_t get_padding_size(const ext_header& header);
413 static std::vector<header_option_type> parse_header_options(const uint8_t* data, size_t size);
414
415 TINS_BEGIN_PACK
416 struct ipv6_header {
417 #if TINS_IS_BIG_ENDIAN
418 uint32_t version:4,
419 traffic_class:8,
420 flow_label:20;
421 uint32_t payload_length:16,
422 next_header:8,
423 hop_limit:8;
424 #else
425 uint8_t traffic_class:4,
426 version:4;
427 uint8_t flow_label[3];
428 uint16_t payload_length;
429 uint8_t next_header;
430 uint8_t hop_limit;
431 #endif
432 uint8_t src_addr[16], dst_addr[16];
433 } TINS_END_PACK;
434
435 ipv6_header header_;
436 headers_type ext_headers_;
437 uint8_t next_header_;
438};
439}
440
441#endif // TINS_IPV6_h
Definition ipv6_address.h:45
Definition ipv6.h:54
address_type src_addr() const
Getter for the src_addr field.
Definition ipv6.h:242
uint16_t payload_length() const
Getter for the payload_length field.
Definition ipv6.h:218
IPv6Address address_type
Definition ipv6.h:64
PDUType pdu_type() const
Getter for the PDU's type.
Definition ipv6.h:339
uint8_t hop_limit() const
Getter for the hop_limit field.
Definition ipv6.h:234
address_type dst_addr() const
Getter for the dst_addr field.
Definition ipv6.h:250
uint8_t next_header() const
Getter for the next_header field.
Definition ipv6.h:226
std::pair< uint8_t, std::vector< uint8_t > > header_option_type
Definition ipv6.h:79
uint8_t traffic_class() const
Getter for the traffic_class field.
Definition ipv6.h:191
PDUOption< uint8_t, IPv6 > ext_header
Definition ipv6.h:69
small_uint< 20 > flow_label() const
Getter for the flow_label field.
Definition ipv6.h:204
ExtensionHeader
Definition ipv6.h:84
TINS_DEPRECATED(void add_ext_header(const ext_header &header))
const headers_type & headers() const
Getter for the IPv6 extension headers.
Definition ipv6.h:258
IPv6 * clone() const
Definition ipv6.h:331
std::vector< ext_header > headers_type
Definition ipv6.h:74
void add_header(ext_header &&header)
Definition ipv6.h:379
void add_header(Args &&... args)
Definition ipv6.h:389
OptionType
Definition ipv6.h:99
small_uint< 4 > version() const
Getter for the version field.
Definition ipv6.h:183
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 store Fragment Extension headers.
Definition ipv6.h:145
Definition ipv6.h:116
The type used to store Routing Extension headers.
Definition ipv6.h:134