mirror of
https://github.com/mfontanini/libtins
synced 2026-01-23 02:35:57 +01:00
Finished porting ICMPv6.
This commit is contained in:
@@ -481,7 +481,39 @@ public:
|
||||
|
||||
static timestamp_type from_option(const option &opt);
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* The type used to store the shortcut limit option.
|
||||
*/
|
||||
struct shortcut_limit_type {
|
||||
uint8_t limit, reserved1;
|
||||
uint32_t reserved2;
|
||||
|
||||
shortcut_limit_type(uint8_t limit = 0)
|
||||
: limit(limit), reserved1(), reserved2()
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
static shortcut_limit_type from_option(const option &opt);
|
||||
};
|
||||
|
||||
/**
|
||||
* The type used to store new advertisement interval option.
|
||||
*/
|
||||
struct new_advert_interval_type {
|
||||
uint16_t reserved;
|
||||
uint32_t interval;
|
||||
|
||||
new_advert_interval_type(uint32_t interval = 0)
|
||||
: reserved(), interval(interval)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
static new_advert_interval_type from_option(const option &opt);
|
||||
};
|
||||
|
||||
/**
|
||||
* \brief Constructs an ICMPv6 object.
|
||||
*
|
||||
@@ -883,12 +915,9 @@ public:
|
||||
/**
|
||||
* \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);
|
||||
void redirect_header(const byte_array &data);
|
||||
|
||||
/**
|
||||
* \brief Setter for the MTU option.
|
||||
@@ -902,14 +931,14 @@ public:
|
||||
*
|
||||
* \param value The shortcut limit option data.
|
||||
*/
|
||||
void shortcut_limit(uint8_t value);
|
||||
void shortcut_limit(const shortcut_limit_type& value);
|
||||
|
||||
/**
|
||||
* \brief Setter for the new advertisement interval option.
|
||||
*
|
||||
* \param value The new advertisement interval option data.
|
||||
*/
|
||||
void new_advert_interval(uint32_t value);
|
||||
void new_advert_interval(const new_advert_interval_type &value);
|
||||
|
||||
/**
|
||||
* \brief Setter for the new home agent information option.
|
||||
@@ -1064,7 +1093,7 @@ public:
|
||||
* This method will throw an option_not_found exception if the
|
||||
* option is not found.
|
||||
*/
|
||||
PDU::serialization_type redirect_header() const;
|
||||
byte_array redirect_header() const;
|
||||
|
||||
/**
|
||||
* \brief Getter for the MTU option.
|
||||
@@ -1080,7 +1109,7 @@ public:
|
||||
* This method will throw an option_not_found exception if the
|
||||
* option is not found.
|
||||
*/
|
||||
uint8_t shortcut_limit() const;
|
||||
shortcut_limit_type shortcut_limit() const;
|
||||
|
||||
/**
|
||||
* \brief Getter for the new advertisement interval option.
|
||||
@@ -1088,7 +1117,7 @@ public:
|
||||
* This method will throw an option_not_found exception if the
|
||||
* option is not found.
|
||||
*/
|
||||
uint32_t new_advert_interval() const;
|
||||
new_advert_interval_type new_advert_interval() const;
|
||||
|
||||
/**
|
||||
* \brief Getter for the new home agent information option.
|
||||
|
||||
@@ -294,33 +294,29 @@ void ICMPv6::prefix_info(prefix_info_type info) {
|
||||
);
|
||||
}
|
||||
|
||||
void ICMPv6::redirect_header(PDU::serialization_type data) {
|
||||
// Reserved fields
|
||||
data.insert(data.begin(), 6, 0);
|
||||
// Padding(if necessary)
|
||||
uint8_t padding = 8 - (data.size() + sizeof(uint8_t) * 2) % 8;
|
||||
if(padding == 8)
|
||||
padding = 0;
|
||||
data.insert(data.end(), padding, 0);
|
||||
void ICMPv6::redirect_header(const byte_array& data) {
|
||||
add_option(option(REDIRECT_HEADER, data.begin(), data.end()));
|
||||
}
|
||||
|
||||
void ICMPv6::mtu(const mtu_type& value) {
|
||||
uint8_t buffer[sizeof(uint16_t) + sizeof(uint32_t)] = {0};
|
||||
*(uint32_t*)buffer = Endian::host_to_be(value.first);
|
||||
*(uint16_t*)buffer = Endian::host_to_be(value.first);
|
||||
*(uint32_t*)(buffer + sizeof(uint16_t)) = Endian::host_to_be(value.second);
|
||||
add_option(option(MTU, sizeof(buffer), buffer));
|
||||
}
|
||||
|
||||
void ICMPv6::shortcut_limit(uint8_t value) {
|
||||
void ICMPv6::shortcut_limit(const shortcut_limit_type &value) {
|
||||
uint8_t buffer[sizeof(uint16_t) + sizeof(uint32_t)] = {0};
|
||||
buffer[0] = value;
|
||||
buffer[0] = value.limit;
|
||||
buffer[1] = value.reserved1;
|
||||
*(uint32_t*)&buffer[2] = Endian::host_to_be(value.reserved2);
|
||||
add_option(option(NBMA_SHORT_LIMIT, sizeof(buffer), buffer));
|
||||
}
|
||||
|
||||
void ICMPv6::new_advert_interval(uint32_t value) {
|
||||
void ICMPv6::new_advert_interval(const new_advert_interval_type &value) {
|
||||
uint8_t buffer[sizeof(uint16_t) + sizeof(uint32_t)] = {0};
|
||||
*((uint32_t*)(buffer + sizeof(uint16_t))) = Endian::host_to_be(value);
|
||||
*(uint16_t*)buffer = Endian::host_to_be(value.reserved);
|
||||
*((uint32_t*)(buffer + sizeof(uint16_t))) = Endian::host_to_be(value.interval);
|
||||
add_option(option(ADVERT_INTERVAL, sizeof(buffer), buffer));
|
||||
}
|
||||
|
||||
@@ -554,30 +550,20 @@ ICMPv6::prefix_info_type ICMPv6::prefix_info() const {
|
||||
return search_and_convert<prefix_info_type>(PREFIX_INFO);
|
||||
}
|
||||
|
||||
PDU::serialization_type ICMPv6::redirect_header() const {
|
||||
const option *opt = search_option(REDIRECT_HEADER);
|
||||
if(!opt || opt->data_size() < 6)
|
||||
throw option_not_found();
|
||||
const uint8_t *ptr = opt->data_ptr() + 6;
|
||||
return serialization_type(ptr, ptr + opt->data_size() - 6);
|
||||
byte_array ICMPv6::redirect_header() const {
|
||||
return search_and_convert<PDU::serialization_type>(REDIRECT_HEADER);
|
||||
}
|
||||
|
||||
ICMPv6::mtu_type ICMPv6::mtu() const {
|
||||
return search_and_convert<mtu_type>(MTU);
|
||||
}
|
||||
|
||||
uint8_t ICMPv6::shortcut_limit() const {
|
||||
const option *opt = search_option(NBMA_SHORT_LIMIT);
|
||||
if(!opt || opt->data_size() != sizeof(uint16_t) + sizeof(uint32_t))
|
||||
throw option_not_found();
|
||||
return *opt->data_ptr();
|
||||
ICMPv6::shortcut_limit_type ICMPv6::shortcut_limit() const {
|
||||
return search_and_convert<shortcut_limit_type>(NBMA_SHORT_LIMIT);
|
||||
}
|
||||
|
||||
uint32_t ICMPv6::new_advert_interval() const {
|
||||
const option *opt = search_option(ADVERT_INTERVAL);
|
||||
if(!opt || opt->data_size() != sizeof(uint16_t) + sizeof(uint32_t))
|
||||
throw option_not_found();
|
||||
return Endian::be_to_host(*(const uint32_t*)(opt->data_ptr() + sizeof(uint16_t)));
|
||||
ICMPv6::new_advert_interval_type ICMPv6::new_advert_interval() const {
|
||||
return search_and_convert<new_advert_interval_type>(ADVERT_INTERVAL);
|
||||
}
|
||||
|
||||
ICMPv6::new_ha_info_type ICMPv6::new_home_agent_info() const {
|
||||
@@ -867,5 +853,26 @@ ICMPv6::timestamp_type ICMPv6::timestamp_type::from_option(const option &opt)
|
||||
std::copy(opt.data_ptr(), opt.data_ptr() + 6, output.reserved);
|
||||
return output;
|
||||
}
|
||||
|
||||
ICMPv6::shortcut_limit_type ICMPv6::shortcut_limit_type::from_option(const option &opt)
|
||||
{
|
||||
if(opt.data_size() != 6)
|
||||
throw malformed_option();
|
||||
const uint8_t *ptr = opt.data_ptr();
|
||||
shortcut_limit_type output(*ptr++);
|
||||
output.reserved1 = *ptr++;
|
||||
output.reserved2 = Endian::be_to_host(*(uint32_t*)ptr);
|
||||
return output;
|
||||
}
|
||||
|
||||
ICMPv6::new_advert_interval_type ICMPv6::new_advert_interval_type::from_option(const option &opt)
|
||||
{
|
||||
if(opt.data_size() != 6)
|
||||
throw malformed_option();
|
||||
new_advert_interval_type output;
|
||||
output.reserved = Endian::be_to_host(*(uint16_t*)opt.data_ptr());
|
||||
output.interval = Endian::be_to_host(*(uint32_t*)(opt.data_ptr() + sizeof(uint16_t)));
|
||||
return output;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -209,6 +209,7 @@ TEST_F(ICMPv6Test, RedirectHeader) {
|
||||
ICMPv6 icmp;
|
||||
IP ip = IP("127.0.0.1") / TCP(22);
|
||||
PDU::serialization_type buffer = ip.serialize();
|
||||
buffer.insert(buffer.begin(), 6, 0);
|
||||
icmp.redirect_header(buffer);
|
||||
EXPECT_EQ(buffer, icmp.redirect_header());
|
||||
}
|
||||
@@ -223,13 +224,18 @@ TEST_F(ICMPv6Test, MTU) {
|
||||
TEST_F(ICMPv6Test, ShortcutLimit) {
|
||||
ICMPv6 icmp;
|
||||
icmp.shortcut_limit(123);
|
||||
EXPECT_EQ(icmp.shortcut_limit(), 123);
|
||||
ICMPv6::shortcut_limit_type sl = icmp.shortcut_limit();
|
||||
EXPECT_EQ(123, sl.limit);
|
||||
EXPECT_EQ(0, sl.reserved1);
|
||||
EXPECT_EQ(0, sl.reserved2);
|
||||
}
|
||||
|
||||
TEST_F(ICMPv6Test, NewAdvertisementInterval) {
|
||||
ICMPv6 icmp;
|
||||
icmp.new_advert_interval(0x9a8df7);
|
||||
EXPECT_EQ(icmp.new_advert_interval(), 0x9a8df7U);
|
||||
ICMPv6::new_advert_interval_type data = icmp.new_advert_interval();
|
||||
EXPECT_EQ(0x9a8df7U, data.interval);
|
||||
EXPECT_EQ(0, data.reserved);
|
||||
}
|
||||
|
||||
TEST_F(ICMPv6Test, NewHomeAgentInformation) {
|
||||
|
||||
Reference in New Issue
Block a user