1
0
mirror of https://github.com/mfontanini/libtins synced 2026-01-28 04:34:27 +01:00

Properly handle MLDv1 on ICMP

This commit is contained in:
Matias Fontanini
2016-03-17 21:49:06 -07:00
parent 6a69d1ff6c
commit 1f4be63d08
3 changed files with 57 additions and 16 deletions

View File

@@ -47,13 +47,13 @@ using Tins::Memory::OutputMemoryStream;
namespace Tins {
ICMPv6::ICMPv6(Types tp)
: options_size_(), reach_time_(0), retrans_timer_(0), mlqm_() {
: options_size_(), reach_time_(0), retrans_timer_(0), mlqm_(), use_mldv2_(true) {
memset(&header_, 0, sizeof(header_));
type(tp);
}
ICMPv6::ICMPv6(const uint8_t* buffer, uint32_t total_sz)
: options_size_(), reach_time_(0), retrans_timer_(0), mlqm_() {
: options_size_(), reach_time_(0), retrans_timer_(0), mlqm_(), use_mldv2_(true) {
InputMemoryStream stream(buffer, total_sz);
stream.read(header_);
if (has_target_addr()) {
@@ -77,12 +77,16 @@ ICMPv6::ICMPv6(const uint8_t* buffer, uint32_t total_sz)
}
else if (type() == MGM_QUERY) {
stream.read(multicast_address_);
stream.read(mlqm_);
int sources_count = stream.read_be<uint16_t>();
while (sources_count--) {
ipaddress_type address;
stream.read(address);
sources_.push_back(address);
// MLDv1 ends here
use_mldv2_ = stream;
if (stream) {
stream.read(mlqm_);
int sources_count = stream.read_be<uint16_t>();
while (sources_count--) {
ipaddress_type address;
stream.read(address);
sources_.push_back(address);
}
}
}
// Retrieve options
@@ -232,8 +236,11 @@ uint32_t ICMPv6::header_size() const {
}
}
else if (type() == MGM_QUERY) {
extra += ipaddress_type::address_size + sizeof(mlqm_) + sizeof(uint16_t) +
ipaddress_type::address_size * sources_.size();
extra += ipaddress_type::address_size;
if (use_mldv2_) {
extra += sizeof(mlqm_) + sizeof(uint16_t) +
ipaddress_type::address_size * sources_.size();
}
}
return sizeof(header_) + options_size_ + extra +
(has_target_addr() ? ipaddress_type::address_size : 0) +
@@ -315,12 +322,15 @@ void ICMPv6::write_serialization(uint8_t* buffer, uint32_t total_sz, const PDU*
}
else if (type() == MGM_QUERY) {
stream.write(multicast_address_);
stream.write(mlqm_);
stream.write_be<uint16_t>(sources_.size());
typedef sources_list::const_iterator iterator;
for (iterator iter = sources_.begin(); iter != sources_.end(); ++iter) {
stream.write(*iter);
}
// Only write this if we're using MLDv2
if (use_mldv2_) {
stream.write(mlqm_);
stream.write_be<uint16_t>(sources_.size());
typedef sources_list::const_iterator iterator;
for (iterator iter = sources_.begin(); iter != sources_.end(); ++iter) {
stream.write(*iter);
}
}
}
for (options_type::const_iterator it = options_.begin(); it != options_.end(); ++it) {
write_option(*it, stream);
@@ -414,6 +424,10 @@ void ICMPv6::write_option(const option& opt, OutputMemoryStream& stream) {
stream.write(opt.data_ptr(), opt.data_size());
}
void ICMPv6::use_mldv2(bool value) {
use_mldv2_ = value;
}
const ICMPv6::option* ICMPv6::search_option(OptionTypes type) const {
// Search for the iterator. If we found something, return it, otherwise return nullptr.
options_type::const_iterator iter = search_option_iterator(type);