779 lines
21 KiB
C++
779 lines
21 KiB
C++
/*
|
|
* Copyright (c) 2017, Matias Fontanini
|
|
* All rights reserved.
|
|
*
|
|
* Redistribution and use in source and binary forms, with or without
|
|
* modification, are permitted provided that the following conditions are
|
|
* met:
|
|
*
|
|
* * Redistributions of source code must retain the above copyright
|
|
* notice, this list of conditions and the following disclaimer.
|
|
* * Redistributions in binary form must reproduce the above
|
|
* copyright notice, this list of conditions and the following disclaimer
|
|
* in the documentation and/or other materials provided with the
|
|
* distribution.
|
|
*
|
|
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
|
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
|
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
|
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
|
* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
|
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
|
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
|
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
|
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
|
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
|
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
|
*
|
|
*/
|
|
|
|
#ifndef TINS_IP_H
|
|
#define TINS_IP_H
|
|
|
|
#include <tins/pdu.h>
|
|
#include <tins/small_uint.h>
|
|
#include <tins/endianness.h>
|
|
#include <tins/ip_address.h>
|
|
#include <tins/pdu_option.h>
|
|
#include <tins/macros.h>
|
|
#include <tins/cxxstd.h>
|
|
|
|
namespace Tins {
|
|
namespace Memory {
|
|
|
|
class OutputMemoryStream;
|
|
|
|
} // Memory
|
|
|
|
/**
|
|
* \class IP
|
|
* \brief Class that represents an IP PDU.
|
|
*
|
|
* By default, IP PDUs are initialized, setting TTL to IP::DEFAULT_TTL,
|
|
* id field to 1 and version to 4. Taking this into account, users
|
|
* should set destination and source port and would be enough to send one.
|
|
*
|
|
* When IP is the lowest layer on a packet, and the packet is serialized
|
|
* this willc heck if the source address is different than 0.0.0.0. If it is,
|
|
* the address of the interface in which the packet is going to be sent
|
|
* is retrieved (by using the routing table and the destination address)
|
|
* and set as the source address. If you don't want this behaviour, simply
|
|
* set the source address to 0.0.0.0.
|
|
*/
|
|
class TINS_API IP : public PDU {
|
|
public:
|
|
/**
|
|
* This PDU's flag.
|
|
*/
|
|
static const PDU::PDUType pdu_flag = PDU::IP;
|
|
|
|
/**
|
|
* The type used to store addresses.
|
|
*/
|
|
typedef IPv4Address address_type;
|
|
|
|
/**
|
|
* Type used to represent the different IP flags.
|
|
*/
|
|
enum Flags {
|
|
FLAG_RESERVED = 4,
|
|
DONT_FRAGMENT = 2,
|
|
MORE_FRAGMENTS = 1
|
|
};
|
|
|
|
/**
|
|
* \brief Enum indicating the option's class.
|
|
*
|
|
* Enum OptionClass represents the different classes of
|
|
* IP Options.
|
|
*/
|
|
enum OptionClass {
|
|
CONTROL = 0,
|
|
MEASUREMENT = 2
|
|
};
|
|
|
|
/**
|
|
* \brief Enum indicating the option's id number.
|
|
*
|
|
* Enum Option indicates the possible IP Options.
|
|
*/
|
|
enum OptionNumber {
|
|
END = 0,
|
|
NOOP = 1,
|
|
SEC = 2,
|
|
LSRR = 3,
|
|
TIMESTAMP = 4,
|
|
EXTSEC = 5,
|
|
RR = 7,
|
|
SID = 8,
|
|
SSRR = 9,
|
|
MTUPROBE = 11,
|
|
MTUREPLY = 12,
|
|
EIP = 17,
|
|
TR = 18,
|
|
ADDEXT = 19,
|
|
RTRALT = 20,
|
|
SDB = 21,
|
|
DPS = 23,
|
|
UMP = 24,
|
|
QS = 25
|
|
};
|
|
|
|
/**
|
|
* \brief The type used to represent an option's type.
|
|
*/
|
|
TINS_BEGIN_PACK
|
|
struct option_identifier {
|
|
#if TINS_IS_LITTLE_ENDIAN
|
|
uint8_t number:5,
|
|
op_class:2,
|
|
copied:1;
|
|
#elif TINS_IS_BIG_ENDIAN
|
|
uint8_t copied:1,
|
|
op_class:2,
|
|
number:5;
|
|
#endif
|
|
/**
|
|
* \brief Default constructor.
|
|
*
|
|
* Initializes every field to 0.
|
|
*/
|
|
option_identifier()
|
|
#if TINS_IS_LITTLE_ENDIAN
|
|
: number(0), op_class(0), copied(0) {}
|
|
#else
|
|
: copied(0), op_class(0), number(0) {}
|
|
#endif
|
|
|
|
/**
|
|
* \brief Constructs this option from a single uint8_t value.
|
|
*
|
|
* This parses the value and initializes each field with the
|
|
* appropriate value.
|
|
*
|
|
* \param value The value to be parsed and used for
|
|
* initialization
|
|
*/
|
|
option_identifier(uint8_t value)
|
|
#if TINS_IS_LITTLE_ENDIAN
|
|
: number(value & 0x1f),
|
|
op_class((value >> 5) & 0x03),
|
|
copied((value >> 7) & 0x01) {}
|
|
#elif TINS_IS_BIG_ENDIAN
|
|
: copied((value >> 7) & 0x01),
|
|
op_class((value >> 5) & 0x03),
|
|
number(value & 0x1f) {}
|
|
#endif
|
|
|
|
/**
|
|
* Constructor using user provided values for each field.
|
|
* \param number The number field value.
|
|
* \param op_class The option class field value.
|
|
* \param copied The copied field value.
|
|
*/
|
|
option_identifier(OptionNumber number, OptionClass op_class,
|
|
small_uint<1> copied)
|
|
#if TINS_IS_LITTLE_ENDIAN
|
|
: number(static_cast<uint8_t>(number)), op_class(static_cast<uint8_t>(op_class)), copied(copied) {}
|
|
#else
|
|
: copied(copied), op_class(static_cast<uint8_t>(op_class)), number(static_cast<uint8_t>(number)) {}
|
|
#endif
|
|
|
|
/**
|
|
* \brief Equality operator.
|
|
*/
|
|
bool operator==(const option_identifier& rhs) const {
|
|
return number == rhs.number && op_class == rhs.op_class && copied == rhs.copied;
|
|
}
|
|
} TINS_END_PACK;
|
|
|
|
/**
|
|
* The IP options type.
|
|
*/
|
|
typedef PDUOption<option_identifier, IP> option;
|
|
|
|
/**
|
|
* The type of the security option.
|
|
*/
|
|
struct security_type {
|
|
uint16_t security, compartments;
|
|
uint16_t handling_restrictions;
|
|
small_uint<24> transmission_control;
|
|
|
|
security_type(uint16_t sec = 0,
|
|
uint16_t comp = 0,
|
|
uint16_t hand_res = 0,
|
|
small_uint<24> tcc = 0)
|
|
: security(sec), compartments(comp),
|
|
handling_restrictions(hand_res), transmission_control(tcc) { }
|
|
|
|
static security_type from_option(const option& opt);
|
|
};
|
|
|
|
/**
|
|
* The type of the Loose Source and Record Route
|
|
*/
|
|
struct generic_route_option_type {
|
|
typedef std::vector<address_type> routes_type;
|
|
|
|
uint8_t pointer;
|
|
routes_type routes;
|
|
|
|
generic_route_option_type(uint8_t ptr = 0, routes_type rts = routes_type())
|
|
: pointer(ptr), routes(rts) {}
|
|
|
|
static generic_route_option_type from_option(const option& opt);
|
|
};
|
|
|
|
/**
|
|
* The type of the Loose Source and Record Route
|
|
*/
|
|
typedef generic_route_option_type lsrr_type;
|
|
|
|
/**
|
|
* The type of the Strict Source and Record Route
|
|
*/
|
|
typedef generic_route_option_type ssrr_type;
|
|
|
|
/**
|
|
* The type of the Record Route
|
|
*/
|
|
typedef generic_route_option_type record_route_type;
|
|
|
|
/**
|
|
* The type used to store IP options.
|
|
*/
|
|
typedef std::vector<option> options_type;
|
|
|
|
/**
|
|
* \brief Extracts metadata for this protocol based on the buffer provided
|
|
*
|
|
* \param buffer Pointer to a buffer
|
|
* \param total_sz Size of the buffer pointed by buffer
|
|
*/
|
|
static metadata extract_metadata(const uint8_t *buffer, uint32_t total_sz);
|
|
|
|
/**
|
|
* \brief Constructor for building the IP PDU.
|
|
*
|
|
* Both the destination and source IP address can be supplied.
|
|
* By default, those fields are initialized using the IP
|
|
* address 0.0.0.0.
|
|
*
|
|
* \param ip_dst The destination ip address(optional).
|
|
* \param ip_src The source ip address(optional).
|
|
*/
|
|
IP(address_type ip_dst = address_type(),
|
|
address_type ip_src = address_type());
|
|
|
|
/**
|
|
* \brief Constructs an IP object from a buffer and adds all
|
|
* identifiable PDUs found in the buffer as children of this
|
|
* one.
|
|
*
|
|
* If there is not enough size for an IP header, a
|
|
* malformed_packet exception is thrown.
|
|
*
|
|
* \param buffer The buffer from which this PDU will be constructed.
|
|
* \param total_sz The total size of the buffer.
|
|
*/
|
|
IP(const uint8_t* buffer, uint32_t total_sz);
|
|
|
|
/* Getters */
|
|
|
|
uint32_t advertised_size() const {
|
|
return static_cast<uint32_t>(tot_len());
|
|
}
|
|
|
|
/**
|
|
* \brief Getter for the header length field.
|
|
*
|
|
* \return The number of dwords the header occupies in an uin8_t.
|
|
*/
|
|
small_uint<4> head_len() const {
|
|
return this->header_.ihl;
|
|
}
|
|
|
|
/**
|
|
* \brief Getter for the type of service field.
|
|
*
|
|
* \return The this IP PDU's type of service.
|
|
*/
|
|
uint8_t tos() const {
|
|
return header_.tos;
|
|
}
|
|
|
|
/**
|
|
* \brief Getter for the total length field.
|
|
*
|
|
* \return The total length of this IP PDU.
|
|
*/
|
|
uint16_t tot_len() const {
|
|
return Endian::be_to_host(header_.tot_len);
|
|
}
|
|
|
|
/**
|
|
* \brief Getter for the id field.
|
|
*
|
|
* \return The id for this IP PDU.
|
|
*/
|
|
uint16_t id() const {
|
|
return Endian::be_to_host(header_.id);
|
|
}
|
|
|
|
/**
|
|
* \brief Getter for the fragment offset field.
|
|
*
|
|
* This method is deprecated. Use IP::fragment_offset and IP::flags.
|
|
*
|
|
* \deprecated
|
|
* \return The fragment offset for this IP PDU.
|
|
* \sa IP::fragment_offset
|
|
* \sa IP::flags
|
|
*/
|
|
TINS_DEPRECATED(uint16_t frag_off() const) {
|
|
return Endian::be_to_host(header_.frag_off);
|
|
}
|
|
|
|
/**
|
|
* \brief Getter for the fragment offset field.
|
|
*
|
|
* This will return the fragment offset field, as present in the packet,
|
|
* which indicates the offset of this fragment in blocks of 8 bytes.
|
|
*
|
|
* \return The fragment offset, measured in units of 8 byte blocks
|
|
*/
|
|
small_uint<13> fragment_offset() const {
|
|
return Endian::be_to_host(header_.frag_off) & 0x1fff;
|
|
}
|
|
|
|
/**
|
|
* \brief Getter for the flags field.
|
|
*
|
|
* \return The IP flags field
|
|
*/
|
|
Flags flags() const {
|
|
return static_cast<Flags>(Endian::be_to_host(header_.frag_off) >> 13);
|
|
}
|
|
|
|
/**
|
|
* \brief Getter for the time to live field.
|
|
*
|
|
* \return The time to live for this IP PDU.
|
|
*/
|
|
uint8_t ttl() const {
|
|
return header_.ttl;
|
|
}
|
|
|
|
/**
|
|
* \brief Getter for the protocol field.
|
|
*
|
|
* \return The protocol for this IP PDU.
|
|
*/
|
|
uint8_t protocol() const {
|
|
return header_.protocol;
|
|
}
|
|
|
|
/**
|
|
* \brief Getter for the checksum field.
|
|
*
|
|
* \return The checksum for this IP PDU.
|
|
*/
|
|
uint16_t checksum() const {
|
|
return Endian::be_to_host(header_.check);
|
|
}
|
|
|
|
/**
|
|
* \brief Getter for the source address field.
|
|
*
|
|
* \return The source address for this IP PDU.
|
|
*/
|
|
address_type src_addr() const {
|
|
return address_type(header_.saddr);
|
|
}
|
|
|
|
/**
|
|
* \brief Getter for the destination address field.
|
|
* \return The destination address for this IP PDU.
|
|
*/
|
|
address_type dst_addr() const {
|
|
return address_type(header_.daddr);
|
|
}
|
|
|
|
/**
|
|
* \brief Getter for the version field.
|
|
* \return The version for this IP PDU.
|
|
*/
|
|
small_uint<4> version() const {
|
|
return header_.version;
|
|
}
|
|
|
|
/**
|
|
* \brief Getter for the IP options.
|
|
* \return The stored options.
|
|
*/
|
|
const options_type& options() const {
|
|
return options_;
|
|
}
|
|
|
|
/* Setters */
|
|
|
|
/**
|
|
* \brief Setter for the type of service field.
|
|
*
|
|
* \param new_tos The new type of service.
|
|
*/
|
|
void tos(uint8_t new_tos);
|
|
|
|
/**
|
|
* \brief Setter for the id field.
|
|
*
|
|
* \param new_id The new id.
|
|
*/
|
|
void id(uint16_t new_id);
|
|
|
|
/**
|
|
* \brief Setter for the fragment offset field.
|
|
*
|
|
* This method is deprecated. Use IP::fragment_offset and IP::flags.
|
|
*
|
|
* \deprecated
|
|
* \param new_frag_off The new fragment offset.
|
|
* \sa IP::fragment_offset
|
|
* \sa IP::flags
|
|
*/
|
|
TINS_DEPRECATED(void frag_off(uint16_t new_frag_off));
|
|
|
|
/**
|
|
* \brief Setter for the fragment offset field.
|
|
*
|
|
* The value provided is measured in units of 8 byte blocks. This means that
|
|
* if you want this packet to have a fragment offset of <i>X</i>,
|
|
* you need to provide <i>X / 8</i> as the argument to this method.
|
|
*
|
|
* \param new_frag_off The new fragment offset, measured in units of 8 byte blocks.
|
|
*/
|
|
void fragment_offset(small_uint<13> new_frag_off);
|
|
|
|
/**
|
|
* \brief Setter for the flags field.
|
|
*
|
|
* \param new_flags The new IP flags field value.
|
|
*/
|
|
void flags(Flags new_flags);
|
|
|
|
/**
|
|
* \brief Setter for the time to live field.
|
|
*
|
|
* \param new_ttl The new time to live.
|
|
*/
|
|
void ttl(uint8_t new_ttl);
|
|
|
|
/**
|
|
* \brief Setter for the protocol field.
|
|
*
|
|
* Note that this protocol will be overwritten using the
|
|
* inner_pdu's protocol type during serialization unless the IP
|
|
* datagram is fragmented.
|
|
*
|
|
* If the packet is fragmented and was originally sniffed, the
|
|
* original protocol type will be kept when serialized.
|
|
*
|
|
* If this packet has been crafted manually and the inner_pdu
|
|
* is, for example, a RawPDU, then setting the protocol yourself
|
|
* is necessary.
|
|
*
|
|
* \param new_protocol The new protocol.
|
|
*/
|
|
void protocol(uint8_t new_protocol);
|
|
|
|
/**
|
|
* \brief Setter for the source address field.
|
|
*
|
|
* \param ip The source address to be set.
|
|
*/
|
|
void src_addr(address_type ip);
|
|
|
|
/**
|
|
* \brief Setter for the destination address field.
|
|
*
|
|
* \param ip The destination address to be set.
|
|
*/
|
|
void dst_addr(address_type ip);
|
|
|
|
/**
|
|
* \brief Setter for the version field.
|
|
*
|
|
* \param ver The version field to be set.
|
|
*/
|
|
void version(small_uint<4> ver);
|
|
|
|
/**
|
|
* \brief Adds an IP option.
|
|
*
|
|
* The option is added after the last option in the option
|
|
* fields.
|
|
*
|
|
* \param opt The option to be added
|
|
*/
|
|
void add_option(const option& opt);
|
|
|
|
#if TINS_IS_CXX11
|
|
/**
|
|
* \brief Adds an IP option.
|
|
*
|
|
* The option is move-constructed.
|
|
*
|
|
* \param opt The option to be added.
|
|
*/
|
|
void add_option(option &&opt) {
|
|
options_.push_back(std::move(opt));
|
|
}
|
|
|
|
/**
|
|
* \brief Adds an IP option.
|
|
*
|
|
* The option is constructed from the provided parameters.
|
|
*
|
|
* \param args The arguments to be used in the option's
|
|
* constructor.
|
|
*/
|
|
template<typename... Args>
|
|
void add_option(Args&&... args) {
|
|
options_.emplace_back(std::forward<Args>(args)...);
|
|
}
|
|
#endif
|
|
|
|
/**
|
|
* \brief Removes an IP option.
|
|
*
|
|
* If there are multiple options of the given type, only the first one
|
|
* will be removed.
|
|
*
|
|
* \param type The type of the option to be removed.
|
|
* \return true if the option was removed, false otherwise.
|
|
*/
|
|
bool remove_option(option_identifier id);
|
|
|
|
/**
|
|
* \brief Searchs for an option that matchs the given flag.
|
|
*
|
|
* If the option is not found, a null pointer is returned.
|
|
* Deleting the returned pointer will result in <b>undefined
|
|
* behaviour</b>.
|
|
*
|
|
* \param id The option identifier to be searched.
|
|
*/
|
|
const option* search_option(option_identifier id) const;
|
|
|
|
// Option setters
|
|
|
|
/**
|
|
* \brief Adds an End Of List option.
|
|
*/
|
|
void eol();
|
|
|
|
/**
|
|
* \brief Adds a NOP option.
|
|
*/
|
|
void noop();
|
|
|
|
/**
|
|
* \brief Adds a security option.
|
|
*
|
|
* \param data The data to be stored in this option.
|
|
*/
|
|
void security(const security_type& data);
|
|
|
|
/**
|
|
* \brief Adds a Loose Source and Record Route option.
|
|
*
|
|
* \param data The data to be stored in this option.
|
|
*/
|
|
void lsrr(const lsrr_type& data) {
|
|
add_route_option(131, data);
|
|
}
|
|
|
|
/**
|
|
* \brief Adds a Strict Source and Record Route option.
|
|
*
|
|
* \param data The data to be stored in this option.
|
|
*/
|
|
void ssrr(const ssrr_type& data) {
|
|
add_route_option(137, data);
|
|
}
|
|
|
|
/**
|
|
* \brief Adds a Record Route option.
|
|
*
|
|
* \param data The data to be stored in this option.
|
|
*/
|
|
void record_route(const record_route_type& data) {
|
|
add_route_option(7, data);
|
|
}
|
|
|
|
/**
|
|
* \brief Adds a Stream Identifier option.
|
|
*
|
|
* \param stream_id The stream id to be stored in this option.
|
|
*/
|
|
void stream_identifier(uint16_t stream_id);
|
|
|
|
// Option getters
|
|
|
|
/**
|
|
* \brief Searchs and returns a security option.
|
|
*
|
|
* If no such option exists, an option_not_found exception
|
|
* is thrown.
|
|
*
|
|
* \return security_type containing the option found.
|
|
*/
|
|
security_type security() const;
|
|
|
|
/**
|
|
* \brief Searchs and returns a Loose Source and Record Route
|
|
* option.
|
|
*
|
|
* If no such option exists, an option_not_found exception
|
|
* is thrown.
|
|
*
|
|
* \return lsrr_type containing the option found.
|
|
*/
|
|
lsrr_type lsrr() const {
|
|
return search_route_option(131);
|
|
}
|
|
|
|
/**
|
|
* \brief Searchs and returns a Strict Source and Record Route
|
|
* option.
|
|
*
|
|
* If no such option exists, an option_not_found exception
|
|
* is thrown.
|
|
*
|
|
* \return ssrr_type containing the option found.
|
|
*/
|
|
ssrr_type ssrr() const {
|
|
return search_route_option(137);
|
|
}
|
|
|
|
/**
|
|
* \brief Searchs and returns a Record Route option.
|
|
*
|
|
* If no such option exists, an option_not_found exception
|
|
* is thrown.
|
|
*
|
|
* \return record_route_type containing the option found.
|
|
*/
|
|
record_route_type record_route() const {
|
|
return search_route_option(7);
|
|
}
|
|
|
|
/**
|
|
* \brief Searchs and returns a Stream Identifier option.
|
|
*
|
|
* If no such option exists, an option_not_found exception
|
|
* is thrown.
|
|
*
|
|
* \return uint16_t containing the option found.
|
|
*/
|
|
uint16_t stream_identifier() const;
|
|
|
|
/* Virtual methods */
|
|
|
|
/**
|
|
* \brief Returns the header size.
|
|
*
|
|
* This method overrides PDU::header_size. \sa PDU::header_size
|
|
*/
|
|
uint32_t header_size() const;
|
|
|
|
/**
|
|
* \sa PDU::send()
|
|
*/
|
|
void send(PacketSender& sender, const NetworkInterface &);
|
|
|
|
/**
|
|
* \brief Check whether ptr points to a valid response for this PDU.
|
|
*
|
|
* \sa PDU::matches_response
|
|
* \param ptr The pointer to the buffer.
|
|
* \param total_sz The size of the buffer.
|
|
*/
|
|
bool matches_response(const uint8_t* ptr, uint32_t total_sz) const;
|
|
|
|
/**
|
|
* \brief Receives a matching response for this packet.
|
|
*
|
|
* \sa PDU::recv_response
|
|
* \param sender The packet sender which will receive the packet.
|
|
*/
|
|
PDU* recv_response(PacketSender& sender, const NetworkInterface &);
|
|
|
|
/**
|
|
* Indicates whether this PDU is fragmented.
|
|
*
|
|
* \return true if this PDU is fragmented, false otherwise.
|
|
*/
|
|
bool is_fragmented() const;
|
|
|
|
/**
|
|
* \brief Getter for the PDU's type.
|
|
* \sa PDU::pdu_type
|
|
*/
|
|
PDUType pdu_type() const {
|
|
return pdu_flag;
|
|
}
|
|
|
|
/**
|
|
* \sa PDU::clone
|
|
*/
|
|
IP* clone() const {
|
|
return new IP(*this);
|
|
}
|
|
private:
|
|
static const uint8_t DEFAULT_TTL;
|
|
|
|
TINS_BEGIN_PACK
|
|
struct ip_header {
|
|
#if TINS_IS_LITTLE_ENDIAN
|
|
uint8_t ihl:4,
|
|
version:4;
|
|
#else
|
|
uint8_t version:4,
|
|
ihl:4;
|
|
#endif
|
|
uint8_t tos;
|
|
uint16_t tot_len;
|
|
uint16_t id;
|
|
uint16_t frag_off;
|
|
uint8_t ttl;
|
|
uint8_t protocol;
|
|
uint16_t check;
|
|
uint32_t saddr;
|
|
uint32_t daddr;
|
|
} TINS_END_PACK;
|
|
|
|
void head_len(small_uint<4> new_head_len);
|
|
void tot_len(uint16_t new_tot_len);
|
|
|
|
void prepare_for_serialize();
|
|
uint32_t calculate_options_size() const;
|
|
uint32_t pad_options_size(uint32_t size) const;
|
|
void init_ip_fields();
|
|
void write_serialization(uint8_t* buffer, uint32_t total_sz);
|
|
void write_option(const option& opt, Memory::OutputMemoryStream& stream);
|
|
void add_route_option(option_identifier id, const generic_route_option_type& data);
|
|
generic_route_option_type search_route_option(option_identifier id) const;
|
|
void checksum(uint16_t new_check);
|
|
options_type::const_iterator search_option_iterator(option_identifier id) const;
|
|
options_type::iterator search_option_iterator(option_identifier id);
|
|
|
|
options_type options_;
|
|
ip_header header_;
|
|
};
|
|
|
|
} // Tins
|
|
|
|
#endif // TINS_IP_H
|