mirror of
https://github.com/mfontanini/libtins
synced 2026-01-23 02:35:57 +01:00
Implemented every DHCPv6 option getter/setter, except for those involving DUIDs.
This commit is contained in:
551
include/dhcpv6.h
551
include/dhcpv6.h
@@ -120,6 +120,109 @@ public:
|
||||
container_type value_;
|
||||
};
|
||||
|
||||
/**
|
||||
* The message types.
|
||||
*/
|
||||
enum MessageType {
|
||||
SOLICIT = 1,
|
||||
ADVERTISE,
|
||||
REQUEST,
|
||||
CONFIRM,
|
||||
RENEW,
|
||||
REBIND,
|
||||
REPLY,
|
||||
RELEASE,
|
||||
DECLINE,
|
||||
RECONFIGURE,
|
||||
INFO_REQUEST,
|
||||
RELAY_FORWARD,
|
||||
RELAY_REPLY,
|
||||
LEASE_QUERY,
|
||||
LEASE_QUERY_REPLY,
|
||||
LEASE_QUERY_DONE,
|
||||
LEASE_QUERY_DATA
|
||||
};
|
||||
|
||||
/**
|
||||
* The DHCPv6 options.
|
||||
*/
|
||||
enum Option {
|
||||
CLIENTID = 1,
|
||||
SERVERID,
|
||||
IA_NA,
|
||||
IA_TA,
|
||||
IA_ADDR,
|
||||
OPTION_REQUEST,
|
||||
PREFERENCE,
|
||||
ELAPSED_TIME,
|
||||
RELAY_MSG,
|
||||
AUTH = 11,
|
||||
UNICAST,
|
||||
STATUS_CODE,
|
||||
RAPID_COMMIT,
|
||||
USER_CLASS,
|
||||
VENDOR_CLASS,
|
||||
VENDOR_OPTS,
|
||||
INTERFACE_ID,
|
||||
RECONF_MSG,
|
||||
RECONF_ACCEPT,
|
||||
SIP_SERVER_D,
|
||||
SIP_SERVER_A,
|
||||
DNS_SERVERS,
|
||||
DOMAIN_LIST,
|
||||
IA_PD,
|
||||
IAPREFIX,
|
||||
NIS_SERVERS,
|
||||
NISP_SERVERS,
|
||||
NIS_DOMAIN_NAME,
|
||||
NISP_DOMAIN_NAME,
|
||||
SNTP_SERVERS,
|
||||
INFORMATION_REFRESH_TIME,
|
||||
BCMCS_SERVER_D,
|
||||
BCMCS_SERVER_A,
|
||||
GEOCONF_CIVIC = 36,
|
||||
REMOTE_ID,
|
||||
SUBSCRIBER_ID,
|
||||
CLIENT_FQDN,
|
||||
PANA_AGENT,
|
||||
NEW_POSIX_TIMEZONE,
|
||||
NEW_TZDB_TIMEZONE,
|
||||
ERO,
|
||||
LQ_QUERY,
|
||||
CLIENT_DATA,
|
||||
CLT_TIME,
|
||||
LQ_RELAY_DATA,
|
||||
LQ_CLIENT_LINK,
|
||||
MIP6_HNIDF,
|
||||
MIP6_VDINF,
|
||||
V6_LOST,
|
||||
CAPWAP_AC_V6,
|
||||
RELAY_ID,
|
||||
NTP_SERVER,
|
||||
V6_ACCESS_DOMAIN,
|
||||
SIP_UA_CS_LIST,
|
||||
BOOTFILE_URL,
|
||||
BOOTFILE_PARAM,
|
||||
CLIENT_ARCH_TYPE,
|
||||
NII,
|
||||
GEOLOCATION,
|
||||
AFTR_NAME,
|
||||
ERP_LOCAL_DOMAIN_NAME,
|
||||
RSOO,
|
||||
PD_EXCLUDE,
|
||||
VSS,
|
||||
MIP6_IDINF,
|
||||
MIP6_UDINF,
|
||||
MIP6_HNP,
|
||||
MIP6_HAA,
|
||||
MIP6_HAF,
|
||||
RDNSS_SELECTION,
|
||||
KRB_PRINCIPAL_NAME,
|
||||
KRB_REALM_NAME,
|
||||
KRB_DEFAULT_REALM_NAME,
|
||||
KRB_KDC
|
||||
};
|
||||
|
||||
/**
|
||||
* The type used to store the DHCPv6 options.
|
||||
*/
|
||||
@@ -135,6 +238,136 @@ public:
|
||||
*/
|
||||
static const PDU::PDUType pdu_flag = PDU::DHCPv6;
|
||||
|
||||
/**
|
||||
* The type used to store the Identity Association for Non-Temporary
|
||||
* Addresses option.
|
||||
*/
|
||||
struct ia_na_type {
|
||||
typedef std::vector<uint8_t> options_type;
|
||||
|
||||
uint32_t id, t1, t2;
|
||||
options_type options;
|
||||
|
||||
ia_na_type(uint32_t id = 0, uint32_t t1 = 0, uint32_t t2 = 0,
|
||||
const options_type& options = options_type())
|
||||
: id(id), t1(t1), t2(t2), options(options) {}
|
||||
};
|
||||
|
||||
/**
|
||||
* The type used to store the Identity Association for Temporary
|
||||
* Addresses option.
|
||||
*/
|
||||
struct ia_ta_type {
|
||||
typedef std::vector<uint8_t> options_type;
|
||||
|
||||
uint32_t id;
|
||||
options_type options;
|
||||
|
||||
ia_ta_type(uint32_t id = 0,
|
||||
const options_type& options = options_type())
|
||||
: id(id), options(options) {}
|
||||
};
|
||||
|
||||
/**
|
||||
* The type used to store the Identity Association Address option.
|
||||
*/
|
||||
struct ia_address_type {
|
||||
typedef std::vector<uint8_t> options_type;
|
||||
|
||||
ipaddress_type address;
|
||||
uint32_t preferred_lifetime, valid_lifetime;
|
||||
options_type options;
|
||||
|
||||
ia_address_type(ipaddress_type address = ipaddress_type(),
|
||||
uint32_t preferred_lifetime = 0, uint32_t valid_lifetime = 0,
|
||||
const options_type& options = options_type())
|
||||
: address(address), preferred_lifetime(preferred_lifetime),
|
||||
valid_lifetime(valid_lifetime), options(options) {}
|
||||
};
|
||||
|
||||
/**
|
||||
* The type used to store the Authentication option.
|
||||
*/
|
||||
struct authentication_type {
|
||||
typedef std::vector<uint8_t> auth_info_type;
|
||||
|
||||
uint8_t protocol, algorithm, rdm;
|
||||
uint64_t replay_detection;
|
||||
auth_info_type auth_info;
|
||||
|
||||
authentication_type(uint8_t protocol = 0, uint8_t algorithm = 0,
|
||||
uint8_t rdm = 0, uint64_t replay_detection = 0,
|
||||
const auth_info_type &auth_info = auth_info_type())
|
||||
: protocol(protocol), algorithm(algorithm), rdm(rdm),
|
||||
replay_detection(replay_detection), auth_info(auth_info) {}
|
||||
};
|
||||
|
||||
/**
|
||||
* The type used to store the Status Code option.
|
||||
*/
|
||||
struct status_code_type {
|
||||
uint16_t code;
|
||||
std::string message;
|
||||
|
||||
status_code_type(uint16_t code = 0, const std::string &message = "")
|
||||
: code(code), message(message) { }
|
||||
};
|
||||
|
||||
/**
|
||||
* The type used to store the Vendor-specific Information option.
|
||||
*/
|
||||
struct vendor_info_type {
|
||||
typedef std::vector<uint8_t> data_type;
|
||||
|
||||
uint32_t enterprise_number;
|
||||
data_type data;
|
||||
|
||||
vendor_info_type(uint32_t enterprise_number = 0,
|
||||
const data_type &data = data_type())
|
||||
: enterprise_number(enterprise_number), data(data) { }
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* The type used to store the User Class option's user class data.
|
||||
*/
|
||||
typedef std::vector<uint8_t> class_option_data_type;
|
||||
|
||||
/**
|
||||
* The type used to store the User Class option.
|
||||
*/
|
||||
typedef std::vector<class_option_data_type> user_class_type;
|
||||
|
||||
/**
|
||||
* The type used to store the Vendor Class option.
|
||||
*/
|
||||
struct vendor_class_type {
|
||||
typedef std::vector<class_option_data_type> class_data_type;
|
||||
|
||||
uint32_t enterprise_number;
|
||||
class_data_type vendor_class_data;
|
||||
|
||||
vendor_class_type(uint32_t enterprise_number = 0,
|
||||
const class_data_type &vendor_class_data = class_data_type())
|
||||
: enterprise_number(enterprise_number),
|
||||
vendor_class_data(vendor_class_data) { }
|
||||
};
|
||||
|
||||
/**
|
||||
* The type used to store the Option Request option.
|
||||
*/
|
||||
typedef std::vector<Option> option_request_type;
|
||||
|
||||
/**
|
||||
* The type used to store the Relay Message option.
|
||||
*/
|
||||
typedef std::vector<uint8_t> relay_msg_type;
|
||||
|
||||
/**
|
||||
* The type used to store the Interface-ID option.
|
||||
*/
|
||||
typedef std::vector<uint8_t> interface_id_type;
|
||||
|
||||
/**
|
||||
* Default constructor.
|
||||
*/
|
||||
@@ -150,12 +383,15 @@ public:
|
||||
DHCPv6(const uint8_t *buffer, uint32_t total_sz);
|
||||
|
||||
// Getters
|
||||
|
||||
/**
|
||||
* \brief Getter for the message type field.
|
||||
*
|
||||
* \return The stored message type field.
|
||||
*/
|
||||
uint8_t msg_type() const { return header_data[0]; }
|
||||
MessageType msg_type() const {
|
||||
return static_cast<MessageType>(header_data[0]);
|
||||
}
|
||||
|
||||
/**
|
||||
* \brief Getter for the hop count field.
|
||||
@@ -193,7 +429,7 @@ public:
|
||||
*
|
||||
* \param type The new message type.
|
||||
*/
|
||||
void msg_type(uint8_t type);
|
||||
void msg_type(MessageType type);
|
||||
|
||||
/**
|
||||
* \brief Setter for the hop count field.
|
||||
@@ -223,6 +459,265 @@ public:
|
||||
*/
|
||||
void link_address(const ipaddress_type &addr);
|
||||
|
||||
// Option getters
|
||||
|
||||
/**
|
||||
* \brief Getter for the Identity Association for Non-Temporary
|
||||
* Addresses option.
|
||||
*
|
||||
* This method will throw an option_not_found exception if the
|
||||
* option is not found.
|
||||
*/
|
||||
ia_na_type ia_na() const;
|
||||
|
||||
/**
|
||||
* \brief Getter for the Identity Association for Temporary
|
||||
* Addresses option.
|
||||
*
|
||||
* This method will throw an option_not_found exception if the
|
||||
* option is not found.
|
||||
*/
|
||||
ia_ta_type ia_ta() const;
|
||||
|
||||
/**
|
||||
* \brief Getter for the Identity Association Address option.
|
||||
*
|
||||
* This method will throw an option_not_found exception if the
|
||||
* option is not found.
|
||||
*/
|
||||
ia_address_type ia_address() const;
|
||||
|
||||
/**
|
||||
* \brief Getter for the Option Request option.
|
||||
*
|
||||
* This method will throw an option_not_found exception if the
|
||||
* option is not found.
|
||||
*/
|
||||
option_request_type option_request() const;
|
||||
|
||||
/**
|
||||
* \brief Getter for the Preference option.
|
||||
*
|
||||
* This method will throw an option_not_found exception if the
|
||||
* option is not found.
|
||||
*/
|
||||
uint8_t preference() const;
|
||||
|
||||
/**
|
||||
* \brief Getter for the Elapsed Time option.
|
||||
*
|
||||
* This method will throw an option_not_found exception if the
|
||||
* option is not found.
|
||||
*/
|
||||
uint16_t elapsed_time() const;
|
||||
|
||||
/**
|
||||
* \brief Getter for the Relay Message option.
|
||||
*
|
||||
* This method will throw an option_not_found exception if the
|
||||
* option is not found.
|
||||
*/
|
||||
relay_msg_type relay_message() const;
|
||||
|
||||
/**
|
||||
* \brief Getter for the Authentication option.
|
||||
*
|
||||
* This method will throw an option_not_found exception if the
|
||||
* option is not found.
|
||||
*/
|
||||
authentication_type authentication() const;
|
||||
|
||||
/**
|
||||
* \brief Getter for the Server Unicast option.
|
||||
*
|
||||
* This method will throw an option_not_found exception if the
|
||||
* option is not found.
|
||||
*/
|
||||
ipaddress_type server_unicast() const;
|
||||
|
||||
/**
|
||||
* \brief Getter for the Server Unicast option.
|
||||
*
|
||||
* This method will throw an option_not_found exception if the
|
||||
* option is not found.
|
||||
*/
|
||||
status_code_type status_code() const;
|
||||
|
||||
/**
|
||||
* \brief Getter for the Rapid Commit option.
|
||||
*
|
||||
* This method will throw an option_not_found exception if the
|
||||
* option is not found.
|
||||
*/
|
||||
bool has_rapid_commit() const;
|
||||
|
||||
/**
|
||||
* \brief Getter for the User Class option.
|
||||
*
|
||||
* This method will throw an option_not_found exception if the
|
||||
* option is not found.
|
||||
*/
|
||||
user_class_type user_class() const;
|
||||
|
||||
/**
|
||||
* \brief Getter for the Vendor Class option.
|
||||
*
|
||||
* This method will throw an option_not_found exception if the
|
||||
* option is not found.
|
||||
*/
|
||||
vendor_class_type vendor_class() const;
|
||||
|
||||
/**
|
||||
* \brief Getter for the Vendor-specific Information option.
|
||||
*
|
||||
* This method will throw an option_not_found exception if the
|
||||
* option is not found.
|
||||
*/
|
||||
vendor_info_type vendor_info() const;
|
||||
|
||||
/**
|
||||
* \brief Getter for the Interface ID option.
|
||||
*
|
||||
* This method will throw an option_not_found exception if the
|
||||
* option is not found.
|
||||
*/
|
||||
interface_id_type interface_id() const;
|
||||
|
||||
/**
|
||||
* \brief Getter for the Reconfigure Message option.
|
||||
*
|
||||
* This method will throw an option_not_found exception if the
|
||||
* option is not found.
|
||||
*/
|
||||
uint8_t reconfigure_msg() const;
|
||||
|
||||
/**
|
||||
* \brief Getter for the Reconfigure Accept option.
|
||||
*
|
||||
* This method will throw an option_not_found exception if the
|
||||
* option is not found.
|
||||
*/
|
||||
bool has_reconfigure_accept() const;
|
||||
|
||||
// Option setters
|
||||
|
||||
/**
|
||||
* \brief Setter for the Identity Association for Non-Temporary
|
||||
* Addresses option.
|
||||
*
|
||||
* \param value The new IA_NA option data.
|
||||
*/
|
||||
void ia_na(const ia_na_type &value);
|
||||
|
||||
/**
|
||||
* \brief Setter for the Identity Association for Temporary
|
||||
* Addresses option.
|
||||
*
|
||||
* \param value The new IA_TA option data.
|
||||
*/
|
||||
void ia_ta(const ia_ta_type &value);
|
||||
|
||||
/**
|
||||
* \brief Setter for the Identity Association Address option.
|
||||
*
|
||||
* \param value The new IA Address option data.
|
||||
*/
|
||||
void ia_address(const ia_address_type &value);
|
||||
|
||||
/**
|
||||
* \brief Setter for the Identity Association Address option.
|
||||
*
|
||||
* \param value The new Option Request option data.
|
||||
*/
|
||||
void option_request(const option_request_type &value);
|
||||
|
||||
/**
|
||||
* \brief Setter for the Preference option.
|
||||
*
|
||||
* \param value The new Preference option data.
|
||||
*/
|
||||
void preference(uint8_t value);
|
||||
|
||||
/**
|
||||
* \brief Setter for the Elapsed Time option.
|
||||
*
|
||||
* \param value The new Elapsed Time option data.
|
||||
*/
|
||||
void elapsed_time(uint16_t value);
|
||||
|
||||
/**
|
||||
* \brief Setter for the Relay Message option.
|
||||
*
|
||||
* \param value The new Relay Message option data.
|
||||
*/
|
||||
void relay_message(const relay_msg_type &value);
|
||||
|
||||
/**
|
||||
* \brief Setter for the Authentication option.
|
||||
*
|
||||
* \param value The new Authentication option data.
|
||||
*/
|
||||
void authentication(const authentication_type &value);
|
||||
|
||||
/**
|
||||
* \brief Setter for the Server Unicast option.
|
||||
*
|
||||
* \param value The new Server Unicast option data.
|
||||
*/
|
||||
void server_unicast(const ipaddress_type &value);
|
||||
|
||||
/**
|
||||
* \brief Setter for the Status Code option.
|
||||
*
|
||||
* \param value The new Status Code option data.
|
||||
*/
|
||||
void status_code(const status_code_type &value);
|
||||
|
||||
/**
|
||||
* \brief Adds a Rapid Commit option.
|
||||
*/
|
||||
void rapid_commit();
|
||||
|
||||
/**
|
||||
* \brief Setter for the User Class option.
|
||||
*
|
||||
* \param value The new User Class option data.
|
||||
*/
|
||||
void user_class(const user_class_type &value);
|
||||
|
||||
/**
|
||||
* \brief Setter for the Vendor Class option.
|
||||
*
|
||||
* \param value The new Vendor Class option data.
|
||||
*/
|
||||
void vendor_class(const vendor_class_type &value);
|
||||
|
||||
/**
|
||||
* \brief Setter for the Vendor-specific Information option.
|
||||
*
|
||||
* \param value The new Vendor-specific Information option data.
|
||||
*/
|
||||
void vendor_info(const vendor_info_type &value);
|
||||
|
||||
/**
|
||||
* \brief Setter for the Interface ID option.
|
||||
*
|
||||
* \param value The new Interface ID option data.
|
||||
*/
|
||||
void interface_id(const interface_id_type &value);
|
||||
|
||||
/**
|
||||
* \brief Setter for the Reconfigure Message option.
|
||||
*
|
||||
* \param value The new Reconfigure Message option data.
|
||||
*/
|
||||
void reconfigure_msg(uint8_t value);
|
||||
|
||||
/**
|
||||
* \brief Adds a Reconfigure Accept option.
|
||||
*/
|
||||
void reconfigure_accept();
|
||||
|
||||
// Other stuff
|
||||
|
||||
/**
|
||||
@@ -249,8 +744,8 @@ public:
|
||||
*
|
||||
* \param id The option identifier to be searched.
|
||||
*/
|
||||
const dhcpv6_option *search_option(uint16_t id) const;
|
||||
|
||||
const dhcpv6_option *search_option(Option id) const;
|
||||
|
||||
// PDU stuff
|
||||
|
||||
/**
|
||||
@@ -275,6 +770,54 @@ public:
|
||||
private:
|
||||
void write_serialization(uint8_t *buffer, uint32_t total_sz, const PDU *);
|
||||
uint8_t* write_option(const dhcpv6_option &option, uint8_t* buffer) const;
|
||||
|
||||
template<template <typename> class Functor>
|
||||
const dhcpv6_option *safe_search_option(Option opt, uint32_t size) const {
|
||||
const dhcpv6_option *option = search_option(opt);
|
||||
if(!option || Functor<uint32_t>()(option->data_size(), size))
|
||||
throw option_not_found();
|
||||
return option;
|
||||
}
|
||||
|
||||
template<typename InputIterator>
|
||||
void class_option_data2option(InputIterator start, InputIterator end,
|
||||
std::vector<uint8_t>& buffer, size_t start_index = 0)
|
||||
{
|
||||
size_t index = start_index;
|
||||
while(start != end) {
|
||||
buffer.resize(buffer.size() + sizeof(uint16_t) + start->size());
|
||||
*(uint16_t*)&buffer[index] = Endian::host_to_be<uint16_t>(start->size());
|
||||
index += sizeof(uint16_t);
|
||||
std::copy(start->begin(), start->end(), buffer.begin() + index);
|
||||
index += start->size();
|
||||
|
||||
start++;
|
||||
}
|
||||
}
|
||||
|
||||
template<typename OutputType>
|
||||
OutputType option2class_option_data(const uint8_t *ptr, uint32_t total_sz) const
|
||||
{
|
||||
typedef typename OutputType::value_type value_type;
|
||||
OutputType output;
|
||||
size_t index = 0;
|
||||
while(index + 2 < total_sz) {
|
||||
uint16_t size = Endian::be_to_host(
|
||||
*(const uint16_t*)(ptr + index)
|
||||
);
|
||||
index += sizeof(uint16_t);
|
||||
if(index + size > total_sz)
|
||||
throw option_not_found();
|
||||
output.push_back(
|
||||
value_type(ptr + index, ptr + index + size)
|
||||
);
|
||||
index += size;
|
||||
}
|
||||
if(index != total_sz)
|
||||
throw option_not_found();
|
||||
return output;
|
||||
}
|
||||
|
||||
|
||||
uint8_t header_data[4];
|
||||
uint32_t options_size;
|
||||
|
||||
377
src/dhcpv6.cpp
377
src/dhcpv6.cpp
@@ -84,9 +84,9 @@ void DHCPv6::add_option(const dhcpv6_option &option) {
|
||||
options_.push_back(option);
|
||||
}
|
||||
|
||||
const DHCPv6::dhcpv6_option *DHCPv6::search_option(uint16_t id) const {
|
||||
const DHCPv6::dhcpv6_option *DHCPv6::search_option(Option id) const {
|
||||
for(options_type::const_iterator it = options_.begin(); it != options_.end(); ++it) {
|
||||
if(it->option() == id)
|
||||
if(it->option() == static_cast<uint16_t>(id))
|
||||
return &*it;
|
||||
}
|
||||
return 0;
|
||||
@@ -103,8 +103,8 @@ uint8_t* DHCPv6::write_option(const dhcpv6_option &option, uint8_t* buffer) cons
|
||||
);
|
||||
}
|
||||
|
||||
void DHCPv6::msg_type(uint8_t type) {
|
||||
header_data[0] = type;
|
||||
void DHCPv6::msg_type(MessageType type) {
|
||||
header_data[0] = static_cast<uint8_t>(type);
|
||||
}
|
||||
|
||||
void DHCPv6::hop_count(uint8_t count) {
|
||||
@@ -144,4 +144,373 @@ void DHCPv6::write_serialization(uint8_t *buffer, uint32_t total_sz, const PDU *
|
||||
for(options_type::const_iterator it = options_.begin(); it != options_.end(); ++it)
|
||||
buffer = write_option(*it, buffer);
|
||||
}
|
||||
|
||||
|
||||
// ********************************************************************
|
||||
// Option getters
|
||||
// ********************************************************************
|
||||
|
||||
DHCPv6::ia_na_type DHCPv6::ia_na() const {
|
||||
const dhcpv6_option *opt = safe_search_option<std::less>(
|
||||
IA_NA, sizeof(uint32_t) * 3
|
||||
);
|
||||
const uint8_t *ptr = opt->data_ptr() + sizeof(uint32_t) * 3;
|
||||
const uint32_t *ptr_32 = (const uint32_t*)opt->data_ptr();
|
||||
DHCPv6::ia_na_type output;
|
||||
output.id = Endian::be_to_host(*ptr_32++);
|
||||
output.t1 = Endian::be_to_host(*ptr_32++);
|
||||
output.t2 = Endian::be_to_host(*ptr_32++);
|
||||
output.options.assign(ptr, opt->data_ptr() + opt->data_size());
|
||||
return output;
|
||||
}
|
||||
|
||||
DHCPv6::ia_ta_type DHCPv6::ia_ta() const {
|
||||
const dhcpv6_option *opt = safe_search_option<std::less>(
|
||||
IA_TA, sizeof(uint32_t)
|
||||
);
|
||||
const uint8_t *ptr = opt->data_ptr() + sizeof(uint32_t);
|
||||
const uint32_t *ptr_32 = (const uint32_t*)opt->data_ptr();
|
||||
DHCPv6::ia_ta_type output;
|
||||
output.id = Endian::be_to_host(*ptr_32++);
|
||||
output.options.assign(ptr, opt->data_ptr() + opt->data_size());
|
||||
return output;
|
||||
}
|
||||
|
||||
DHCPv6::ia_address_type DHCPv6::ia_address() const {
|
||||
const dhcpv6_option *opt = safe_search_option<std::less>(
|
||||
IA_ADDR, sizeof(uint32_t) * 2 + ipaddress_type::address_size
|
||||
);
|
||||
const uint8_t *ptr = opt->data_ptr() + sizeof(uint32_t) * 2 + ipaddress_type::address_size;
|
||||
const uint32_t *ptr_32 = (const uint32_t*)(opt->data_ptr() + ipaddress_type::address_size);
|
||||
DHCPv6::ia_address_type output;
|
||||
output.address = opt->data_ptr();
|
||||
output.preferred_lifetime = Endian::be_to_host(*ptr_32++);
|
||||
output.valid_lifetime = Endian::be_to_host(*ptr_32++);
|
||||
output.options.assign(ptr, opt->data_ptr() + opt->data_size());
|
||||
return output;
|
||||
}
|
||||
|
||||
DHCPv6::option_request_type DHCPv6::option_request() const {
|
||||
const dhcpv6_option *opt = safe_search_option<std::less>(
|
||||
OPTION_REQUEST, 2
|
||||
);
|
||||
const uint16_t *ptr = (const uint16_t*)opt->data_ptr(),
|
||||
*end = (const uint16_t*)(opt->data_ptr() + opt->data_size());
|
||||
option_request_type output;
|
||||
while(ptr < end) {
|
||||
output.push_back(
|
||||
static_cast<Option>(Endian::be_to_host(*ptr++))
|
||||
);
|
||||
}
|
||||
return output;
|
||||
}
|
||||
|
||||
uint8_t DHCPv6::preference() const {
|
||||
const dhcpv6_option *opt = safe_search_option<std::not_equal_to>(
|
||||
PREFERENCE, 1
|
||||
);
|
||||
return *opt->data_ptr();
|
||||
}
|
||||
|
||||
uint16_t DHCPv6::elapsed_time() const {
|
||||
const dhcpv6_option *opt = safe_search_option<std::not_equal_to>(
|
||||
ELAPSED_TIME, 2
|
||||
);
|
||||
return Endian::be_to_host(
|
||||
*(const uint16_t*)opt->data_ptr()
|
||||
);
|
||||
}
|
||||
|
||||
DHCPv6::relay_msg_type DHCPv6::relay_message() const {
|
||||
const dhcpv6_option *opt = safe_search_option<std::less>(
|
||||
RELAY_MSG, 1
|
||||
);
|
||||
return relay_msg_type(
|
||||
opt->data_ptr(),
|
||||
opt->data_ptr() + opt->data_size()
|
||||
);
|
||||
}
|
||||
|
||||
DHCPv6::authentication_type DHCPv6::authentication() const {
|
||||
const dhcpv6_option *opt = safe_search_option<std::less>(
|
||||
AUTH, sizeof(uint8_t) * 3 + sizeof(uint64_t)
|
||||
);
|
||||
const uint8_t *ptr = opt->data_ptr();
|
||||
authentication_type output;
|
||||
output.protocol = *ptr++;
|
||||
output.algorithm = *ptr++;
|
||||
output.rdm = *ptr++;
|
||||
output.replay_detection = Endian::be_to_host(
|
||||
*(const uint64_t*)ptr
|
||||
);
|
||||
ptr += sizeof(uint64_t);
|
||||
output.auth_info.assign(ptr, opt->data_ptr() + opt->data_size());
|
||||
return output;
|
||||
}
|
||||
|
||||
DHCPv6::ipaddress_type DHCPv6::server_unicast() const {
|
||||
const dhcpv6_option *opt = safe_search_option<std::not_equal_to>(
|
||||
UNICAST, ipaddress_type::address_size
|
||||
);
|
||||
return ipaddress_type(opt->data_ptr());
|
||||
}
|
||||
|
||||
DHCPv6::status_code_type DHCPv6::status_code() const {
|
||||
const dhcpv6_option *opt = safe_search_option<std::less>(
|
||||
STATUS_CODE, sizeof(uint16_t)
|
||||
);
|
||||
status_code_type output;
|
||||
output.code = Endian::be_to_host(*(const uint16_t*)opt->data_ptr());
|
||||
output.message.assign(
|
||||
opt->data_ptr() + sizeof(uint16_t),
|
||||
opt->data_ptr() + opt->data_size()
|
||||
);
|
||||
return output;
|
||||
}
|
||||
|
||||
bool DHCPv6::has_rapid_commit() const {
|
||||
return search_option(RAPID_COMMIT);
|
||||
}
|
||||
|
||||
DHCPv6::user_class_type DHCPv6::user_class() const {
|
||||
const dhcpv6_option *opt = safe_search_option<std::less>(
|
||||
USER_CLASS, sizeof(uint16_t)
|
||||
);
|
||||
return option2class_option_data<user_class_type>(
|
||||
opt->data_ptr(), opt->data_size()
|
||||
);
|
||||
}
|
||||
|
||||
DHCPv6::vendor_class_type DHCPv6::vendor_class() const {
|
||||
const dhcpv6_option *opt = safe_search_option<std::less>(
|
||||
VENDOR_CLASS, sizeof(uint32_t)
|
||||
);
|
||||
typedef vendor_class_type::class_data_type data_type;
|
||||
vendor_class_type output;
|
||||
output.enterprise_number = Endian::be_to_host(
|
||||
*(const uint32_t*)opt->data_ptr()
|
||||
);
|
||||
output.vendor_class_data = option2class_option_data<data_type>(
|
||||
opt->data_ptr() + sizeof(uint32_t),
|
||||
opt->data_size() - sizeof(uint32_t)
|
||||
);
|
||||
|
||||
return output;
|
||||
}
|
||||
|
||||
DHCPv6::vendor_info_type DHCPv6::vendor_info() const {
|
||||
const dhcpv6_option *opt = safe_search_option<std::less>(
|
||||
VENDOR_OPTS, sizeof(uint32_t)
|
||||
);
|
||||
vendor_info_type output;
|
||||
output.enterprise_number = Endian::be_to_host(
|
||||
*(const uint32_t*)opt->data_ptr()
|
||||
);
|
||||
output.data.assign(
|
||||
opt->data_ptr() + sizeof(uint32_t),
|
||||
opt->data_ptr() + opt->data_size()
|
||||
);
|
||||
return output;
|
||||
}
|
||||
|
||||
DHCPv6::interface_id_type DHCPv6::interface_id() const {
|
||||
const dhcpv6_option *opt = safe_search_option<std::equal_to>(
|
||||
INTERFACE_ID, 0
|
||||
);
|
||||
return interface_id_type(
|
||||
opt->data_ptr(),
|
||||
opt->data_ptr() + opt->data_size()
|
||||
);
|
||||
}
|
||||
|
||||
uint8_t DHCPv6::reconfigure_msg() const {
|
||||
return *safe_search_option<std::not_equal_to>(
|
||||
RECONF_MSG, 1
|
||||
)->data_ptr();
|
||||
}
|
||||
|
||||
bool DHCPv6::has_reconfigure_accept() const {
|
||||
return search_option(RECONF_ACCEPT);
|
||||
}
|
||||
|
||||
// ********************************************************************
|
||||
// Option setters
|
||||
// ********************************************************************
|
||||
|
||||
void DHCPv6::ia_na(const ia_na_type &value) {
|
||||
std::vector<uint8_t> buffer(sizeof(uint32_t) * 3 + value.options.size());
|
||||
uint32_t *ptr = (uint32_t*)&buffer[0];
|
||||
*ptr++ = Endian::host_to_be(value.id);
|
||||
*ptr++ = Endian::host_to_be(value.t1);
|
||||
*ptr++ = Endian::host_to_be(value.t2);
|
||||
std::copy(
|
||||
value.options.begin(),
|
||||
value.options.end(),
|
||||
buffer.begin() + sizeof(uint32_t) * 3
|
||||
);
|
||||
add_option(
|
||||
dhcpv6_option(IA_NA, buffer.begin(), buffer.end())
|
||||
);
|
||||
}
|
||||
|
||||
void DHCPv6::ia_ta(const ia_ta_type &value) {
|
||||
std::vector<uint8_t> buffer(sizeof(uint32_t) + value.options.size());
|
||||
uint32_t *ptr = (uint32_t*)&buffer[0];
|
||||
*ptr++ = Endian::host_to_be(value.id);
|
||||
std::copy(
|
||||
value.options.begin(),
|
||||
value.options.end(),
|
||||
buffer.begin() + sizeof(uint32_t)
|
||||
);
|
||||
add_option(
|
||||
dhcpv6_option(IA_TA, buffer.begin(), buffer.end())
|
||||
);
|
||||
}
|
||||
|
||||
void DHCPv6::ia_address(const ia_address_type &value) {
|
||||
std::vector<uint8_t> buffer(
|
||||
sizeof(uint32_t) * 2 + ipaddress_type::address_size + value.options.size()
|
||||
);
|
||||
uint32_t *ptr = (uint32_t*)&buffer[ipaddress_type::address_size];
|
||||
value.address.copy(&buffer[0]);
|
||||
*ptr++ = Endian::host_to_be(value.preferred_lifetime);
|
||||
*ptr++ = Endian::host_to_be(value.valid_lifetime);
|
||||
std::copy(
|
||||
value.options.begin(),
|
||||
value.options.end(),
|
||||
buffer.begin() + sizeof(uint32_t) * 2 + ipaddress_type::address_size
|
||||
);
|
||||
add_option(
|
||||
dhcpv6_option(IA_ADDR, buffer.begin(), buffer.end())
|
||||
);
|
||||
}
|
||||
|
||||
void DHCPv6::option_request(const option_request_type &value) {
|
||||
typedef option_request_type::const_iterator iterator;
|
||||
|
||||
std::vector<uint8_t> buffer(value.size() * sizeof(uint16_t));
|
||||
size_t index = 0;
|
||||
for(iterator it = value.begin(); it != value.end(); ++it, index += 2)
|
||||
*(uint16_t*)&buffer[index] = Endian::host_to_be<uint16_t>(*it);
|
||||
add_option(
|
||||
dhcpv6_option(OPTION_REQUEST, buffer.begin(), buffer.end())
|
||||
);
|
||||
}
|
||||
|
||||
void DHCPv6::preference(uint8_t value) {
|
||||
add_option(
|
||||
dhcpv6_option(PREFERENCE, 1, &value)
|
||||
);
|
||||
}
|
||||
|
||||
void DHCPv6::elapsed_time(uint16_t value) {
|
||||
value = Endian::host_to_be(value);
|
||||
add_option(
|
||||
dhcpv6_option(ELAPSED_TIME, 2, (const uint8_t*)&value)
|
||||
);
|
||||
}
|
||||
|
||||
void DHCPv6::relay_message(const relay_msg_type &value) {
|
||||
add_option(
|
||||
dhcpv6_option(RELAY_MSG, value.begin(), value.end())
|
||||
);
|
||||
}
|
||||
|
||||
void DHCPv6::authentication(const authentication_type &value) {
|
||||
std::vector<uint8_t> buffer(
|
||||
sizeof(uint8_t) * 3 + sizeof(uint64_t) + value.auth_info.size()
|
||||
);
|
||||
buffer[0] = value.protocol;
|
||||
buffer[1] = value.algorithm;
|
||||
buffer[2] = value.rdm;
|
||||
*(uint64_t*)&buffer[3] = Endian::host_to_be(value.replay_detection);
|
||||
std::copy(
|
||||
value.auth_info.begin(),
|
||||
value.auth_info.end(),
|
||||
buffer.begin() + sizeof(uint8_t) * 3 + sizeof(uint64_t)
|
||||
);
|
||||
add_option(
|
||||
dhcpv6_option(AUTH, buffer.begin(), buffer.end())
|
||||
);
|
||||
}
|
||||
|
||||
void DHCPv6::server_unicast(const ipaddress_type &value) {
|
||||
add_option(
|
||||
dhcpv6_option(UNICAST, value.begin(), value.end())
|
||||
);
|
||||
}
|
||||
|
||||
void DHCPv6::status_code(const status_code_type &value) {
|
||||
std::vector<uint8_t> buffer(sizeof(uint16_t) + value.message.size());
|
||||
*(uint16_t*)&buffer[0] = Endian::host_to_be(value.code);
|
||||
std::copy(
|
||||
value.message.begin(),
|
||||
value.message.end(),
|
||||
buffer.begin() + sizeof(uint16_t)
|
||||
);
|
||||
add_option(
|
||||
dhcpv6_option(STATUS_CODE, buffer.begin(), buffer.end())
|
||||
);
|
||||
}
|
||||
|
||||
void DHCPv6::rapid_commit() {
|
||||
add_option(
|
||||
RAPID_COMMIT
|
||||
);
|
||||
}
|
||||
|
||||
void DHCPv6::user_class(const user_class_type &value) {
|
||||
typedef user_class_type::const_iterator iterator;
|
||||
|
||||
std::vector<uint8_t> buffer;
|
||||
class_option_data2option(value.begin(), value.end(), buffer);
|
||||
add_option(
|
||||
dhcpv6_option(USER_CLASS, buffer.begin(), buffer.end())
|
||||
);
|
||||
}
|
||||
|
||||
void DHCPv6::vendor_class(const vendor_class_type &value) {
|
||||
std::vector<uint8_t> buffer(
|
||||
sizeof(uint32_t)
|
||||
);
|
||||
*(uint32_t*)&buffer[0] = Endian::host_to_be(value.enterprise_number);
|
||||
class_option_data2option(
|
||||
value.vendor_class_data.begin(),
|
||||
value.vendor_class_data.end(),
|
||||
buffer,
|
||||
sizeof(uint32_t)
|
||||
);
|
||||
add_option(
|
||||
dhcpv6_option(VENDOR_CLASS, buffer.begin(), buffer.end())
|
||||
);
|
||||
}
|
||||
|
||||
void DHCPv6::vendor_info(const vendor_info_type &value) {
|
||||
std::vector<uint8_t> buffer(sizeof(uint32_t) + value.data.size());
|
||||
*(uint32_t*)&buffer[0] = Endian::host_to_be(value.enterprise_number);
|
||||
std::copy(
|
||||
value.data.begin(),
|
||||
value.data.end(),
|
||||
buffer.begin() + sizeof(uint32_t)
|
||||
);
|
||||
add_option(
|
||||
dhcpv6_option(VENDOR_OPTS, buffer.begin(), buffer.end())
|
||||
);
|
||||
}
|
||||
|
||||
void DHCPv6::interface_id(const interface_id_type &value) {
|
||||
add_option(
|
||||
dhcpv6_option(INTERFACE_ID, value.begin(), value.end())
|
||||
);
|
||||
}
|
||||
|
||||
void DHCPv6::reconfigure_msg(uint8_t value) {
|
||||
add_option(
|
||||
dhcpv6_option(RECONF_MSG, 1, &value)
|
||||
);
|
||||
}
|
||||
|
||||
void DHCPv6::reconfigure_accept() {
|
||||
add_option(RECONF_ACCEPT);
|
||||
}
|
||||
} // namespace Tins
|
||||
|
||||
@@ -24,20 +24,20 @@ const uint8_t DHCPv6Test::expected_packet[] = {
|
||||
|
||||
TEST_F(DHCPv6Test, DefaultConstructor) {
|
||||
DHCPv6 dhcp;
|
||||
EXPECT_EQ(0, dhcp.msg_type());
|
||||
EXPECT_EQ(0, (int)dhcp.msg_type());
|
||||
EXPECT_EQ(0, dhcp.hop_count());
|
||||
EXPECT_EQ(0, dhcp.transaction_id());
|
||||
}
|
||||
|
||||
TEST_F(DHCPv6Test, ConstructorFromBuffer) {
|
||||
DHCPv6 dhcp(expected_packet, sizeof(expected_packet));
|
||||
EXPECT_EQ(1, dhcp.msg_type());
|
||||
EXPECT_EQ(DHCPv6::SOLICIT, dhcp.msg_type());
|
||||
EXPECT_EQ(0xe828b9, dhcp.transaction_id());
|
||||
EXPECT_TRUE(dhcp.search_option(1));
|
||||
EXPECT_TRUE(dhcp.search_option(3));
|
||||
EXPECT_TRUE(dhcp.search_option(6));
|
||||
EXPECT_TRUE(dhcp.search_option(8));
|
||||
EXPECT_FALSE(dhcp.search_option(2));
|
||||
EXPECT_TRUE(dhcp.search_option(DHCPv6::CLIENTID));
|
||||
EXPECT_TRUE(dhcp.search_option(DHCPv6::IA_NA));
|
||||
EXPECT_TRUE(dhcp.search_option(DHCPv6::ELAPSED_TIME));
|
||||
EXPECT_TRUE(dhcp.search_option(DHCPv6::OPTION_REQUEST));
|
||||
EXPECT_FALSE(dhcp.search_option(DHCPv6::SERVERID));
|
||||
}
|
||||
|
||||
TEST_F(DHCPv6Test, Serialize) {
|
||||
@@ -52,8 +52,8 @@ TEST_F(DHCPv6Test, Serialize) {
|
||||
|
||||
TEST_F(DHCPv6Test, MessageType) {
|
||||
DHCPv6 dhcp;
|
||||
dhcp.msg_type(0x8a);
|
||||
EXPECT_EQ(0x8a, dhcp.msg_type());
|
||||
dhcp.msg_type(DHCPv6::SOLICIT);
|
||||
EXPECT_EQ(DHCPv6::SOLICIT, dhcp.msg_type());
|
||||
}
|
||||
|
||||
TEST_F(DHCPv6Test, HopCount) {
|
||||
@@ -67,3 +67,211 @@ TEST_F(DHCPv6Test, TransactionId) {
|
||||
dhcp.transaction_id(0x8af2ad);
|
||||
EXPECT_EQ(0x8af2ad, dhcp.transaction_id());
|
||||
}
|
||||
|
||||
// Options
|
||||
|
||||
TEST_F(DHCPv6Test, IA_NA) {
|
||||
DHCPv6 dhcp;
|
||||
DHCPv6::ia_na_type data, output;
|
||||
data.id = 0x9283f78a;
|
||||
data.t1 = 0xaf235212;
|
||||
data.t2 = 0x9a8293fa;
|
||||
data.options.push_back(0);
|
||||
data.options.push_back(1);
|
||||
data.options.push_back(2);
|
||||
dhcp.ia_na(data);
|
||||
output = dhcp.ia_na();
|
||||
|
||||
EXPECT_EQ(data.id, output.id);
|
||||
EXPECT_EQ(data.t1, output.t1);
|
||||
EXPECT_EQ(data.t2, output.t2);
|
||||
EXPECT_EQ(data.options, output.options);
|
||||
}
|
||||
|
||||
TEST_F(DHCPv6Test, IA_TA) {
|
||||
DHCPv6 dhcp;
|
||||
DHCPv6::ia_ta_type data, output;
|
||||
data.id = 0x9283f78a;
|
||||
data.options.push_back(0);
|
||||
data.options.push_back(1);
|
||||
data.options.push_back(2);
|
||||
dhcp.ia_ta(data);
|
||||
output = dhcp.ia_ta();
|
||||
|
||||
EXPECT_EQ(data.id, output.id);
|
||||
EXPECT_EQ(data.options, output.options);
|
||||
}
|
||||
|
||||
TEST_F(DHCPv6Test, IA_Address) {
|
||||
DHCPv6 dhcp;
|
||||
DHCPv6::ia_address_type data, output;
|
||||
data.address = "fe00:feaa::1";
|
||||
data.preferred_lifetime = 0x9283f78a;
|
||||
data.valid_lifetime = 0x938fda32;
|
||||
data.options.push_back(0);
|
||||
data.options.push_back(1);
|
||||
data.options.push_back(2);
|
||||
dhcp.ia_address(data);
|
||||
output = dhcp.ia_address();
|
||||
|
||||
EXPECT_EQ(data.address, output.address);
|
||||
EXPECT_EQ(data.preferred_lifetime, output.preferred_lifetime);
|
||||
EXPECT_EQ(data.valid_lifetime, output.valid_lifetime);
|
||||
EXPECT_EQ(data.options, output.options);
|
||||
}
|
||||
|
||||
TEST_F(DHCPv6Test, OptionRequest) {
|
||||
DHCPv6 dhcp;
|
||||
DHCPv6::option_request_type data, output;
|
||||
data.push_back(DHCPv6::IA_ADDR);
|
||||
data.push_back(DHCPv6::IA_NA);
|
||||
|
||||
dhcp.option_request(data);
|
||||
output = dhcp.option_request();
|
||||
|
||||
EXPECT_EQ(data, output);
|
||||
}
|
||||
|
||||
TEST_F(DHCPv6Test, Preference) {
|
||||
DHCPv6 dhcp;
|
||||
dhcp.preference(0x8a);
|
||||
EXPECT_EQ(0x8a, dhcp.preference());
|
||||
}
|
||||
|
||||
TEST_F(DHCPv6Test, ElapsedTime) {
|
||||
DHCPv6 dhcp;
|
||||
dhcp.elapsed_time(0x8a2f);
|
||||
EXPECT_EQ(0x8a2f, dhcp.elapsed_time());
|
||||
}
|
||||
|
||||
TEST_F(DHCPv6Test, RelayMessage) {
|
||||
DHCPv6 dhcp;
|
||||
DHCPv6::relay_msg_type data, output;
|
||||
data.push_back(1);
|
||||
data.push_back(156);
|
||||
data.push_back(12);
|
||||
|
||||
dhcp.relay_message(data);
|
||||
output = dhcp.relay_message();
|
||||
|
||||
EXPECT_EQ(data, output);
|
||||
}
|
||||
|
||||
TEST_F(DHCPv6Test, Authentication) {
|
||||
DHCPv6 dhcp;
|
||||
DHCPv6::authentication_type data, output;
|
||||
data.protocol = 0x92;
|
||||
data.algorithm = 0x8f;
|
||||
data.rdm = 0xa1;
|
||||
data.replay_detection = 0x78ad6d5290398df7;
|
||||
data.auth_info.push_back(0);
|
||||
data.auth_info.push_back(1);
|
||||
data.auth_info.push_back(2);
|
||||
dhcp.authentication(data);
|
||||
output = dhcp.authentication();
|
||||
|
||||
EXPECT_EQ(data.protocol, output.protocol);
|
||||
EXPECT_EQ(data.algorithm, output.algorithm);
|
||||
EXPECT_EQ(data.rdm, output.rdm);
|
||||
EXPECT_EQ(data.replay_detection, output.replay_detection);
|
||||
EXPECT_EQ(data.auth_info, output.auth_info);
|
||||
}
|
||||
|
||||
TEST_F(DHCPv6Test, ServerUnicast) {
|
||||
const IPv6Address addr("fe00:0a9d:dd23::1");
|
||||
DHCPv6 dhcp;
|
||||
dhcp.server_unicast(addr);
|
||||
EXPECT_EQ(addr, dhcp.server_unicast());
|
||||
}
|
||||
|
||||
TEST_F(DHCPv6Test, StatusCode) {
|
||||
DHCPv6 dhcp;
|
||||
DHCPv6::status_code_type data(0x72, "libtins, mah frend"), output;
|
||||
dhcp.status_code(data);
|
||||
output = dhcp.status_code();
|
||||
EXPECT_EQ(data.code, output.code);
|
||||
EXPECT_EQ(data.message, output.message);
|
||||
}
|
||||
|
||||
TEST_F(DHCPv6Test, RapidCommit) {
|
||||
DHCPv6 dhcp;
|
||||
dhcp.rapid_commit();
|
||||
EXPECT_EQ(true, dhcp.has_rapid_commit());
|
||||
}
|
||||
|
||||
TEST_F(DHCPv6Test, UserClass) {
|
||||
DHCPv6 dhcp;
|
||||
DHCPv6::user_class_type data, output;
|
||||
DHCPv6::class_option_data_type user_data;
|
||||
user_data.push_back(22);
|
||||
user_data.push_back(176);
|
||||
data.push_back(user_data);
|
||||
|
||||
user_data.push_back(99);
|
||||
user_data.push_back(231);
|
||||
data.push_back(user_data);
|
||||
|
||||
dhcp.user_class(data);
|
||||
output = dhcp.user_class();
|
||||
|
||||
EXPECT_EQ(data, output);
|
||||
}
|
||||
|
||||
TEST_F(DHCPv6Test, VendorClass) {
|
||||
DHCPv6 dhcp;
|
||||
DHCPv6::vendor_class_type data(15), output;
|
||||
DHCPv6::class_option_data_type user_data;
|
||||
user_data.push_back(22);
|
||||
user_data.push_back(176);
|
||||
data.vendor_class_data.push_back(user_data);
|
||||
|
||||
user_data.push_back(99);
|
||||
user_data.push_back(231);
|
||||
data.vendor_class_data.push_back(user_data);
|
||||
|
||||
dhcp.vendor_class(data);
|
||||
output = dhcp.vendor_class();
|
||||
|
||||
EXPECT_EQ(data.enterprise_number, output.enterprise_number);
|
||||
EXPECT_EQ(data.vendor_class_data, output.vendor_class_data);
|
||||
}
|
||||
|
||||
TEST_F(DHCPv6Test, VendorInfo) {
|
||||
DHCPv6 dhcp;
|
||||
DHCPv6::vendor_info_type data(0x72988fad), output;
|
||||
data.data.push_back(22);
|
||||
data.data.push_back(176);
|
||||
data.data.push_back(99);
|
||||
data.data.push_back(231);
|
||||
|
||||
dhcp.vendor_info(data);
|
||||
output = dhcp.vendor_info();
|
||||
|
||||
EXPECT_EQ(data.enterprise_number, output.enterprise_number);
|
||||
EXPECT_EQ(data.data, output.data);
|
||||
}
|
||||
|
||||
TEST_F(DHCPv6Test, InterfaceID) {
|
||||
DHCPv6 dhcp;
|
||||
DHCPv6::interface_id_type data, output;
|
||||
data.push_back(1);
|
||||
data.push_back(156);
|
||||
data.push_back(12);
|
||||
|
||||
dhcp.interface_id(data);
|
||||
output = dhcp.interface_id();
|
||||
|
||||
EXPECT_EQ(data, output);
|
||||
}
|
||||
|
||||
TEST_F(DHCPv6Test, ReconfigureMsg) {
|
||||
DHCPv6 dhcp;
|
||||
dhcp.reconfigure_msg(0x8a);
|
||||
EXPECT_EQ(0x8a, dhcp.reconfigure_msg());
|
||||
}
|
||||
|
||||
TEST_F(DHCPv6Test, ReconfigureAccept) {
|
||||
DHCPv6 dhcp;
|
||||
dhcp.reconfigure_accept();
|
||||
EXPECT_EQ(true, dhcp.has_reconfigure_accept());
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user