1
0
mirror of https://github.com/mfontanini/libtins synced 2026-01-22 18:25:57 +01:00
Files
libtins/include/icmpv6.h
2013-04-23 20:33:00 -03:00

1238 lines
35 KiB
C++

/*
* Copyright (c) 2012, 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_ICMPV6_H
#define TINS_ICMPV6_H
#include <list>
#include <vector>
#include "macros.h"
#include "pdu.h"
#include "ipv6_address.h"
#include "pdu_option.h"
#include "endianness.h"
#include "small_uint.h"
#include "hw_address.h"
#include "small_uint.h"
#include "cxxstd.h"
namespace Tins {
/**
* Represents an ICMPv6 PDU.
*/
class ICMPv6 : public PDU {
public:
/**
* \brief This PDU's flag.
*/
static const PDU::PDUType pdu_flag = PDU::ICMPv6;
/**
* The types of ICMPv6 messages
*/
enum Types {
DEST_UNREACHABLE = 1,
PACKET_TOOBIG = 2,
TIME_EXCEEDED = 3,
PARAM_PROBLEM = 4,
ECHO_REQUEST = 128,
ECHO_REPLY = 129,
MGM_QUERY = 130,
MGM_REPORT = 131,
MGM_REDUCTION = 132,
ROUTER_SOLICIT = 133,
ROUTER_ADVERT = 134,
NEIGHBOUR_SOLICIT = 135,
NEIGHBOUR_ADVERT = 136,
REDIRECT = 137,
ROUTER_RENUMBER = 137,
NI_QUERY = 139,
NI_REPLY = 140,
MLD2_REPORT = 143,
DHAAD_REQUEST = 144,
DHAAD_REPLY = 145,
MOBILE_PREFIX_SOL = 146,
MOBILE_PREFIX_ADV = 147
};
/**
* The types of ICMPv6 options.
*/
enum OptionTypes {
SOURCE_ADDRESS = 1,
TARGET_ADDRESS,
PREFIX_INFO,
REDIRECT_HEADER,
MTU,
NBMA_SHORT_LIMIT,
ADVERT_INTERVAL,
HOME_AGENT_INFO,
S_ADDRESS_LIST,
T_ADDRESS_LIST,
CGA,
RSA_SIGN,
TIMESTAMP,
NONCE,
TRUST_ANCHOR,
CERTIFICATE,
IP_PREFIX,
NEW_ROUTER_PREFIX,
LINK_ADDRESS,
NAACK,
MAP = 23,
ROUTE_INFO,
RECURSIVE_DNS_SERV,
RA_FLAGS_EXT,
HANDOVER_KEY_REQ,
HANDOVER_KEY_REPLY,
HANDOVER_ASSIST_INFO,
MOBILE_NODE_ID,
DNS_SEARCH_LIST,
PROXY_SIGNATURE,
ADDRESS_REG,
SIXLOWPAN_CONTEXT,
AUTHORITATIVE_BORDER_ROUTER,
CARD_REQUEST = 138,
CARD_REPLY
};
/**
* The type used to store addresses.
*/
typedef IPv6Address ipaddress_type;
/**
* The type used to store addresses.
*/
typedef HWAddress<6> hwaddress_type;
/**
* The type used to represent ICMPv6 options.
*/
typedef PDUOption<uint8_t> option;
/**
* The type used to store options.
*/
typedef std::list<option> options_type;
/**
* \brief The type used to store the new home agent information
* option data.
*
* The first member contains the home agent preference field, while
* the second one contains the home agent lifetime.
*/
typedef std::pair<uint16_t, uint16_t> new_ha_info_type;
/**
* The type used to store the source/target address list options.
*/
typedef std::vector<ipaddress_type> addr_list_type;
/**
* The type used to store the nonce option data.
*/
typedef std::vector<uint8_t> nonce_type;
/**
* \brief The type used to store the neighbour advertisement
* acknowledgement option data.
*
* The first member contains the option code field, while
* the second one contains the status.
*/
typedef std::pair<uint8_t, uint8_t> naack_type;
/**
* \brief The type used to store the link layer address option data.
*/
struct lladdr_type {
typedef std::vector<uint8_t> address_type;
uint8_t option_code;
address_type address;
/**
* Constructor taking an option code and an address.
*
* \param option_code The option code.
* \param address The address to be stored.
*/
lladdr_type(uint8_t option_code = 0,
const address_type &address = address_type())
: option_code(option_code), address(address)
{
}
/**
* \brief Constructor taking an option code and hwaddress_type.
*
* This is a helper constructor, since it'll be common to use
* hwaddress_type as the link layer address.
*
* \param option_code The option code.
* \param address The address to be stored.
*/
lladdr_type(uint8_t option_code,
const hwaddress_type &address)
: option_code(option_code), address(address.begin(), address.end())
{
}
};
/**
* Type type used to store the prefix information option data.
*/
struct prefix_info_type {
uint8_t prefix_len;
small_uint<1> A, L;
uint32_t valid_lifetime,
preferred_lifetime,
reserved2;
ipaddress_type prefix;
prefix_info_type(uint8_t prefix_len=0, small_uint<1> A=0, small_uint<1> L=0,
uint32_t valid_lifetime=0, uint32_t preferred_lifetime=0,
const ipaddress_type &prefix = ipaddress_type())
: prefix_len(prefix_len), A(A), L(L),
valid_lifetime(valid_lifetime), preferred_lifetime(preferred_lifetime),
prefix(prefix) { }
};
/**
* The type used to store the RSA signature option.
*/
struct rsa_sign_type {
typedef std::vector<uint8_t> signature_type;
uint8_t key_hash[16];
signature_type signature;
/**
* \brief Constructs a rsa_sign_type object.
*
* The first parameter must be a random access iterator
* which will be used to initialize the key_hash member.
* It is assumed that std::distance(hash, end_of_hash) >= 16.
*
* The second and third arguments indicate the start and end of
* the sequence which will be used to initialize the signature
* member.
*
* \param hash A random access iterator used to initialize the
* key_hash member.
* \param start A forward iterator pointing to the start of the
* sequence which will be used to initialize the signature member.
* \param end A forward iterator pointing to the end of the
* sequence used to initialize signature.
*/
template<typename RAIterator, typename ForwardIterator>
rsa_sign_type(RAIterator hash, ForwardIterator start, ForwardIterator end)
: signature(start, end)
{
std::copy(hash, hash + sizeof(key_hash), key_hash);
}
/**
* \brief Constructs a rsa_sign_type object.
*
* The first parameter must be a random access iterator
* which will be used to initialize the key_hash member.
* It is assumed that std::distance(hash, end_of_hash) >= 16.
*
*
* \param hash A random access iterator used to initialize the
* key_hash member.
* \param sign The signature to be set.
*/
template<typename RAIterator>
rsa_sign_type(RAIterator hash, const signature_type &sign)
: signature(sign)
{
std::copy(hash, hash + sizeof(key_hash), key_hash);
}
/**
* \brief Default constructs a rsa_sign_type.
*
* The key_hash member will be 0-initialized.
*/
rsa_sign_type()
{
std::fill(key_hash, key_hash + sizeof(key_hash), 0);
}
};
/**
* The type used to store IP address/preffix option.
*/
struct ip_prefix_type {
uint8_t option_code, prefix_len;
ipaddress_type address;
ip_prefix_type(uint8_t option_code = 0, uint8_t prefix_len = 0,
const ipaddress_type &address = ipaddress_type())
: option_code(option_code), prefix_len(prefix_len), address(address)
{}
};
/**
* The type used to store the map option.
*/
struct map_type {
small_uint<4> dist, pref;
small_uint<1> r;
uint32_t valid_lifetime;
ipaddress_type address;
map_type(small_uint<4> dist = 0, small_uint<4> pref = 0,
small_uint<1> r = 0, uint32_t valid_lifetime = 0,
const ipaddress_type &address = ipaddress_type())
: dist(dist), pref(pref), r(r), valid_lifetime(valid_lifetime),
address(address) { }
};
/**
* The type used to store the route information option.
*/
struct route_info_type {
typedef std::vector<uint8_t> prefix_type;
uint8_t prefix_len;
small_uint<2> pref;
uint32_t route_lifetime;
prefix_type prefix;
route_info_type(uint8_t prefix_len = 0, small_uint<2> pref = 0,
uint32_t route_lifetime = 0, const prefix_type &prefix = prefix_type())
: prefix_len(prefix_len), pref(pref), route_lifetime(route_lifetime),
prefix(prefix) { }
};
/**
* The type used to store the recursive DNS servers option.
*/
struct recursive_dns_type {
typedef std::vector<ipaddress_type> servers_type;
uint32_t lifetime;
servers_type servers;
recursive_dns_type(uint32_t lifetime = 0,
const servers_type &servers = servers_type())
: lifetime(lifetime), servers(servers) {}
};
/**
* The type used to store the handover key request option.
*/
struct handover_key_req_type {
typedef std::vector<uint8_t> key_type;
small_uint<4> AT;
key_type key;
handover_key_req_type(small_uint<4> AT = 0,
const key_type &key = key_type())
: AT(AT), key(key) { }
};
/**
* The type used to store the handover key reply option.
*/
struct handover_key_reply_type : handover_key_req_type {
uint16_t lifetime;
handover_key_reply_type(uint16_t lifetime = 0, small_uint<4> AT = 0,
const key_type &key = key_type())
: handover_key_req_type(AT, key), lifetime(lifetime) { }
};
/**
* The type used to store the handover assist information option.
*/
struct handover_assist_info_type {
typedef std::vector<uint8_t> hai_type;
uint8_t option_code;
hai_type hai;
handover_assist_info_type(uint8_t option_code=0,
const hai_type &hai = hai_type())
: option_code(option_code), hai(hai) { }
};
/**
* The type used to store the mobile node identifier option.
*/
struct mobile_node_id_type {
typedef std::vector<uint8_t> mn_type;
uint8_t option_code;
mn_type mn;
mobile_node_id_type(uint8_t option_code=0,
const mn_type &mn = mn_type())
: option_code(option_code), mn(mn) { }
};
/**
* The type used to store the DNS search list option.
*/
struct dns_search_list_type {
typedef std::vector<std::string> domains_type;
uint32_t lifetime;
domains_type domains;
dns_search_list_type(uint32_t lifetime = 0,
const domains_type &domains = domains_type())
: lifetime(lifetime), domains(domains) { }
};
/**
* \brief Constructs an ICMPv6 object.
*
* The type of the constructed object will be an echo request, unless
* you provide another one in the tp parameter.
*
* \param tp The message type of this ICMPv6 object.
*/
ICMPv6(Types tp = ECHO_REQUEST);
/**
* \brief Constructs an ICMPv6 object from a buffer.
*
* If there is not enough size for an ICMPv6 header, a
* malformed_packet exception is thrown.
*
* Any extra data is stored in a RawPDU.
*
* \param buffer The buffer from which this PDU will be constructed.
* \param total_sz The total size of the buffer.
*/
ICMPv6(const uint8_t *buffer, uint32_t total_sz);
// Getters
/**
* \brief Getter for the type field.
* \return The stored type field value.
*/
Types type() const {
return static_cast<Types>(_header.type);
}
/**
* \brief Getter for the code field.
* \return The stored code field value.
*/
uint8_t code() const {
return _header.code;
}
/**
* \brief Getter for the cksum field.
* \return The stored cksum field value.
*/
uint16_t checksum() const {
return Endian::be_to_host(_header.cksum);
}
/**
* \brief Getter for the identifier field.
* \return The stored identifier field value.
*/
uint16_t identifier() const {
return Endian::be_to_host(_header.u_echo.identifier);
}
/**
* \brief Getter for the sequence field.
* \return The stored sequence field value.
*/
uint16_t sequence() const {
return Endian::be_to_host(_header.u_echo.sequence);
}
/**
* \brief Getter for the override field.
* \return The stored override field value.
*/
small_uint<1> override() const {
return _header.u_nd_advt.override;
}
/**
* \brief Getter for the solicited field.
* \return The stored solicited field value.
*/
small_uint<1> solicited() const {
return _header.u_nd_advt.solicited;
}
/**
* \brief Getter for the router field.
* \return The stored router field value.
*/
small_uint<1> router() const {
return _header.u_nd_advt.router;
}
/**
* \brief Getter for the hop_limit field.
* \return The stored hop_limit field value.
*/
uint8_t hop_limit() const {
return _header.u_nd_ra.hop_limit;
}
/**
* \brief Getter for the router_pref field.
* \return The stored router_pref field value.
*/
small_uint<2> router_pref() const {
return _header.u_nd_ra.router_pref;
}
/**
* \brief Getter for the home_agent field.
* \return The stored home_agent field value.
*/
small_uint<1> home_agent() const {
return _header.u_nd_ra.home_agent;
}
/**
* \brief Getter for the other field.
* \return The stored other field value.
*/
small_uint<1> other() const {
return _header.u_nd_ra.other;
}
/**
* \brief Getter for the managed field.
* \return The stored managed field value.
*/
small_uint<1> managed() const {
return _header.u_nd_ra.managed;
}
/**
* \brief Getter for the router_lifetime field.
* \return The stored router_lifetime field value.
*/
uint16_t router_lifetime() const {
return Endian::be_to_host(_header.u_nd_ra.router_lifetime);
}
/**
* \brief Getter for the reachable_time field.
* \return The stored reachable_time field value.
*/
uint32_t reachable_time() const {
return Endian::be_to_host(reach_time);
}
/**
* \brief Getter for the retransmit_timer field.
* \return The stored retransmit_timer field value.
*/
uint32_t retransmit_timer() const {
return Endian::be_to_host(retrans_timer);
}
/**
* \brief Getter for the target address field.
* \return The stored target address field value.
*/
const ipaddress_type &target_addr() const {
return _target_address;
}
/**
* \brief Getter for the destination address field.
* \return The stored destination address field value.
*/
const ipaddress_type &dest_addr() const {
return _dest_address;
}
/**
* \brief Getter for the ICMPv6 options.
* \return The stored options.
*/
const options_type &options() const {
return _options;
}
// Setters
/**
* \brief Setter for the type field.
* \param new_type The new type field value.
*/
void type(Types new_type);
/**
* \brief Setter for the code field.
* \param new_code The new code field value.
*/
void code(uint8_t new_code);
/**
* \brief Setter for the cksum field.
* \param new_cksum The new cksum field value.
*/
void checksum(uint16_t new_cksum);
/**
* \brief Setter for the identifier field.
* \param new_identifier The new identifier field value.
*/
void identifier(uint16_t new_identifier);
/**
* \brief Setter for the sequence field.
* \param new_sequence The new sequence field value.
*/
void sequence(uint16_t new_sequence);
/**
* \brief Setter for the override field.
* \param new_override The new override field value.
*/
void override(small_uint<1> new_override);
/**
* \brief Setter for the solicited field.
* \param new_solicited The new solicited field value.
*/
void solicited(small_uint<1> new_solicited);
/**
* \brief Setter for the router field.
* \param new_router The new router field value.
*/
void router(small_uint<1> new_router);
/**
* \brief Setter for the hop_limit field.
* \param new_hop_limit The new hop_limit field value.
*/
void hop_limit(uint8_t new_hop_limit);
/**
* \brief Setter for the router_pref field.
* \param new_router_pref The new router_pref field value.
*/
void router_pref(small_uint<2> new_router_pref);
/**
* \brief Setter for the home_agent field.
* \param new_home_agent The new home_agent field value.
*/
void home_agent(small_uint<1> new_home_agent);
/**
* \brief Setter for the other field.
* \param new_other The new other field value.
*/
void other(small_uint<1> new_other);
/**
* \brief Setter for the managed field.
* \param new_managed The new managed field value.
*/
void managed(small_uint<1> new_managed);
/**
* \brief Setter for the router_lifetime field.
* \param new_router_lifetime The new router_lifetime field value.
*/
void router_lifetime(uint16_t new_router_lifetime);
/**
* \brief Setter for the target address field.
* \param new_target_addr The new target address field value.
*/
void target_addr(const ipaddress_type &new_target_addr);
/**
* \brief Setter for the destination address field.
* \param new_dest_addr The new destination address field value.
*/
void dest_addr(const ipaddress_type &new_dest_addr);
/**
* \brief Setter for the reachable_time field.
* \param new_reachable_time The new reachable_time field value.
*/
void reachable_time(uint32_t new_reachable_time);
/**
* \brief Setter for the retransmit_timer field.
* \param new_retrans_timer The new retrans_timer field value.
*/
void retransmit_timer(uint32_t new_retrans_timer);
/**
* \brief Getter for the PDU's type.
*
* \sa PDU::pdu_type
*/
PDUType pdu_type() const { return pdu_flag; }
/**
* \brief Checks whether this ICMPv6 object has a target_addr field.
*
* This depends on the type field.
*/
bool has_target_addr() const {
return type() == NEIGHBOUR_SOLICIT ||
type() == NEIGHBOUR_ADVERT ||
type() == REDIRECT;
}
/**
* \brief Checks whether this ICMPv6 object has a target_addr field.
*
* This depends on the type field.
*/
bool has_dest_addr() const {
return type() == REDIRECT;
}
/**
* \brief Adds an ICMPv6 option.
*
* The option is added after the last option in the option
* fields.
*
* \param option The option to be added
*/
void add_option(const option &option);
#if TINS_IS_CXX11
/**
* \brief Adds an ICMPv6 option.
*
* The option is move-constructed.
*
* \param option The option to be added.
*/
void add_option(option &&option) {
internal_add_option(option);
_options.push_back(std::move(option));
}
#endif
/**
* \brief Returns the header size.
*
* This metod overrides PDU::header_size. This size includes the
* payload and options size. \sa PDU::header_size
*/
uint32_t header_size() const;
/**
* \brief Check wether 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 Searchs for an option that matchs the given flag.
*
* If the header 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(OptionTypes id) const;
/**
* \sa PDU::clone
*/
ICMPv6 *clone() const {
return new ICMPv6(*this);
}
// ****************************************************************
// Option setters
// ****************************************************************
/**
* \brief Setter for the source link layer address option.
*
* \param addr The source link layer address.
*/
void source_link_layer_addr(const hwaddress_type &addr);
/**
* \brief Setter for the target link layer address option.
*
* \param addr The target link layer address.
*/
void target_link_layer_addr(const hwaddress_type &addr);
/**
* \brief Setter for the prefix information option.
*
* \param info The prefix information.
*/
void prefix_info(prefix_info_type info);
/**
* \brief Setter for the redirect header option.
*
* This method appends the 6 reserved bytes and inserts the
* necessary padding at the end.
*
* \param data The redirect header option data.
*/
void redirect_header(PDU::serialization_type data);
/**
* \brief Setter for the MTU option.
*
* \param value The MTU option data.
*/
void mtu(uint32_t value);
/**
* \brief Setter for the shortcut limit option.
*
* \param value The shortcut limit option data.
*/
void shortcut_limit(uint8_t value);
/**
* \brief Setter for the new advertisement interval option.
*
* \param value The new advertisement interval option data.
*/
void new_advert_interval(uint32_t value);
/**
* \brief Setter for the new home agent information option.
*
* \param value The new home agent information option data.
*/
void new_home_agent_info(const new_ha_info_type &value);
/**
* \brief Setter for the new source address list option.
*
* \param value The new source address list option data.
*/
void source_addr_list(const addr_list_type &value);
/**
* \brief Setter for the new target address list option.
*
* \param value The new target address list option data.
*/
void target_addr_list(const addr_list_type &value);
/**
* \brief Setter for the new RSA signature option.
*
* \param value The new RSA signature option data.
*/
void rsa_signature(const rsa_sign_type &value);
/**
* \brief Setter for the new timestamp option.
*
* \param value The new timestamp option data.
*/
void timestamp(uint64_t value);
/**
* \brief Setter for the new nonce option.
*
* \param value The new nonce option data.
*/
void nonce(const nonce_type &value);
/**
* \brief Setter for the new IP address/prefix option.
*
* \param value The new IP address/prefix option data.
*/
void ip_prefix(const ip_prefix_type &value);
/**
* \brief Setter for the new link layer address option.
*
* \param value The new link layer address option data.
*/
void link_layer_addr(lladdr_type value);
/**
* \brief Setter for the neighbour advertisement acknowledgement option.
*
* \param value The new naack option data.
*/
void naack(const naack_type &value);
/**
* \brief Setter for the map option.
*
* \param value The new map option data.
*/
void map(const map_type &value);
/**
* \brief Setter for the route information option.
*
* \param value The new route information option data.
*/
void route_info(const route_info_type &value);
/**
* \brief Setter for the recursive DNS servers option.
*
* \param value The new recursive DNS servers option data.
*/
void recursive_dns_servers(const recursive_dns_type &value);
/**
* \brief Setter for the handover key request option.
*
* \param value The new handover key request option data.
*/
void handover_key_request(const handover_key_req_type &value);
/**
* \brief Setter for the handover key reply option.
*
* \param value The new handover key reply option data.
*/
void handover_key_reply(const handover_key_reply_type &value);
/**
* \brief Setter for the handover assist info option.
*
* \param value The new handover assist info option data.
*/
void handover_assist_info(const handover_assist_info_type &value);
/**
* \brief Setter for the mobile node identifier option.
*
* \param value The new mobile node identifier option data.
*/
void mobile_node_identifier(const mobile_node_id_type &value);
/**
* \brief Setter for the DNS search list option.
*
* \param value The new DNS search list option data.
*/
void dns_search_list(const dns_search_list_type &value);
// ****************************************************************
// Option getters
// ****************************************************************
/**
* \brief Getter for the source link layer address option.
*
* This method will throw an option_not_found exception if the
* option is not found.
*/
hwaddress_type source_link_layer_addr() const;
/**
* \brief Getter for the target link layer address option.
*
* This method will throw an option_not_found exception if the
* option is not found.
*/
hwaddress_type target_link_layer_addr() const;
/**
* \brief Getter for the prefix information option.
*
* This method will throw an option_not_found exception if the
* option is not found.
*/
prefix_info_type prefix_info() const;
/**
* \brief Getter for the redirect header option.
*
* This method will throw an option_not_found exception if the
* option is not found.
*/
PDU::serialization_type redirect_header() const;
/**
* \brief Getter for the MTU option.
*
* This method will throw an option_not_found exception if the
* option is not found.
*/
uint32_t mtu() const;
/**
* \brief Getter for the shortcut limit option.
*
* This method will throw an option_not_found exception if the
* option is not found.
*/
uint8_t shortcut_limit() const;
/**
* \brief Getter for the new advertisement interval option.
*
* This method will throw an option_not_found exception if the
* option is not found.
*/
uint32_t new_advert_interval() const;
/**
* \brief Getter for the new home agent information option.
*
* This method will throw an option_not_found exception if the
* option is not found.
*/
new_ha_info_type new_home_agent_info() const;
/**
* \brief Getter for the source address list option.
*
* This method will throw an option_not_found exception if the
* option is not found.
*/
addr_list_type source_addr_list() const;
/**
* \brief Getter for the target address list option.
*
* This method will throw an option_not_found exception if the
* option is not found.
*/
addr_list_type target_addr_list() const;
/**
* \brief Getter for the RSA signature option.
*
* This method will throw an option_not_found exception if the
* option is not found.
*/
rsa_sign_type rsa_signature() const;
/**
* \brief Getter for the timestamp option.
*
* This method will throw an option_not_found exception if the
* option is not found.
*/
uint64_t timestamp() const;
/**
* \brief Getter for the nonce option.
*
* This method will throw an option_not_found exception if the
* option is not found.
*/
nonce_type nonce() const;
/**
* \brief Getter for the IP address/prefix option.
*
* This method will throw an option_not_found exception if the
* option is not found.
*/
ip_prefix_type ip_prefix() const;
/**
* \brief Getter for the link layer address option.
*
* This method will throw an option_not_found exception if the
* option is not found.
*/
lladdr_type link_layer_addr() const;
/**
* \brief Getter for the neighbour advertisement acknowledgement
* option.
*
* This method will throw an option_not_found exception if the
* option is not found.
*/
naack_type naack() const;
/**
* \brief Getter for the map option.
*
* This method will throw an option_not_found exception if the
* option is not found.
*/
map_type map() const;
/**
* \brief Getter for the route information option.
*
* This method will throw an option_not_found exception if the
* option is not found.
*/
route_info_type route_info() const;
/**
* \brief Getter for the recursive dns servers option.
*
* This method will throw an option_not_found exception if the
* option is not found.
*/
recursive_dns_type recursive_dns_servers() const;
/**
* \brief Getter for the handover key request option.
*
* This method will throw an option_not_found exception if the
* option is not found.
*/
handover_key_req_type handover_key_request() const;
/**
* \brief Getter for the handover key reply option.
*
* This method will throw an option_not_found exception if the
* option is not found.
*/
handover_key_reply_type handover_key_reply() const;
/**
* \brief Getter for the handover key reply option.
*
* This method will throw an option_not_found exception if the
* option is not found.
*/
handover_assist_info_type handover_assist_info() const;
/**
* \brief Getter for the mobile node identifier option.
*
* This method will throw an option_not_found exception if the
* option is not found.
*/
mobile_node_id_type mobile_node_identifier() const;
/**
* \brief Getter for the mobile node identifier option.
*
* This method will throw an option_not_found exception if the
* option is not found.
*/
dns_search_list_type dns_search_list() const;
private:
TINS_BEGIN_PACK
struct icmp6hdr {
uint8_t type;
uint8_t code;
uint16_t cksum;
union {
struct {
uint16_t identifier;
uint16_t sequence;
} u_echo;
struct {
#if TINS_IS_LITTLE_ENDIAN
uint32_t reserved:5,
override:1,
solicited:1,
router:1,
reserved2:24;
#else
uint32_t router:1,
solicited:1,
override:1,
reserved:29;
#endif
} u_nd_advt;
struct {
uint8_t hop_limit;
#if TINS_IS_LITTLE_ENDIAN
uint8_t reserved:3,
router_pref:2,
home_agent:1,
other:1,
managed:1;
#else
uint8_t managed:1,
other:1,
home_agent:1,
router_pref:2,
reserved:3;
#endif
uint16_t router_lifetime;
} u_nd_ra;
};
} TINS_END_PACK;
void internal_add_option(const option &option);
void write_serialization(uint8_t *buffer, uint32_t total_sz, const PDU *parent);
bool has_options() const;
uint8_t *write_option(const option &opt, uint8_t *buffer);
void parse_options(const uint8_t *&buffer, uint32_t &total_sz);
void add_addr_list(uint8_t type, const addr_list_type &value);
addr_list_type search_addr_list(OptionTypes type) const;
template<template <typename> class Functor>
const option *safe_search_option(OptionTypes opt, uint32_t size) const {
const option *option = search_option(opt);
if(!option || Functor<uint32_t>()(option->data_size(), size))
throw option_not_found();
return option;
}
icmp6hdr _header;
ipaddress_type _target_address, _dest_address;
options_type _options;
uint32_t _options_size;
uint32_t reach_time, retrans_timer;
};
}
#endif // TINS_ICMPV6_H