2
0
mirror of https://gitlab.isc.org/isc-projects/kea synced 2025-08-24 18:57:41 +00:00
kea/src/lib/dhcp/option6_auth.cc

133 lines
4.0 KiB
C++
Raw Normal View History

2022-05-23 17:38:46 +03:00
// Copyright (C) 2018-2022 Internet Systems Consortium, Inc. ("ISC")
//
// This Source Code Form is subject to the terms of the Mozilla Public
// License, v. 2.0. If a copy of the MPL was not distributed with this
// file, You can obtain one at http://mozilla.org/MPL/2.0/.
#include <config.h>
#include <dhcp/dhcp6.h>
#include <dhcp/libdhcp++.h>
#include <dhcp/option6_auth.h>
#include <dhcp/option_space.h>
#include <exceptions/exceptions.h>
#include <util/io_utilities.h>
#include <util/encode/hex.h>
#include <sstream>
#include <stdint.h>
using namespace std;
using namespace isc::util;
namespace isc {
namespace dhcp {
Option6Auth::Option6Auth(const uint8_t proto, const uint8_t algo,
const uint8_t method, const uint64_t rdm,
const std::vector<uint8_t>& info)
: Option(Option::V6, D6O_AUTH),
protocol_(proto), algorithm_(algo),
rdm_method_(method), rdm_value_(rdm),
auth_info_(info) {
}
OptionPtr
Option6Auth::clone() const {
return (cloneInternal<Option6Auth>());
}
void
Option6Auth::pack(isc::util::OutputBuffer& buf, bool) const {
2018-06-18 15:51:16 +02:00
if (buf.getCapacity() < (OPTION6_AUTH_MIN_LEN + OPTION6_HASH_MSG_LEN + OPTION6_HDR)) {
isc_throw(OutOfRange, "Option " << type_ << "Buffer too small for"
"packing data");
}
//header = option code + length
buf.writeUint16(type_);
// length = 11 bytes fixed field length+ length of auth information
buf.writeUint16(11 + uint16_t(auth_info_.size()));
// protocol 1 byte
buf.writeUint8(protocol_);
2021-01-22 01:36:41 +02:00
// algorithm 1 byte
buf.writeUint8(algorithm_);
// replay detection method
buf.writeUint8(rdm_method_);
// replay detection value
buf.writeUint64( rdm_value_);
// authentication information for reconfig msg
// should have zero
for (auto i : auth_info_) {
buf.writeUint8(i);
}
}
void
Option6Auth::packHashInput(isc::util::OutputBuffer& buf) const {
2018-06-18 15:51:16 +02:00
if (buf.getCapacity() < (OPTION6_AUTH_MIN_LEN + OPTION6_HASH_MSG_LEN + OPTION6_HDR)) {
isc_throw(OutOfRange, "Option " << type_ << "Buffer too small for"
"computing hash input");
}
//header = option code + length
buf.writeUint16(type_);
// length = 11 bytes fixed field length+ length of auth information
buf.writeUint16(OPTION6_AUTH_MIN_LEN + OPTION6_HASH_MSG_LEN);
// protocol 1 byte
buf.writeUint8(protocol_);
2021-01-22 01:36:41 +02:00
// algorithm 1 byte
buf.writeUint8(algorithm_);
// replay detection method
buf.writeUint8(rdm_method_);
// replay detection value
buf.writeUint64(rdm_value_);
// authentication information for reconfig msg
// should have zero
for (uint8_t i = 0; i < OPTION6_HASH_MSG_LEN; i++) {
buf.writeUint8(0);
}
}
void
Option6Auth::unpack(OptionBufferConstIter begin,
OptionBufferConstIter end) {
// throw if it contains length less than minimum size of the auth option
if (distance(begin, end) < Option6Auth::OPTION6_AUTH_MIN_LEN) {
isc_throw(OutOfRange, "Option " << type_ << " truncated");
}
protocol_ = *begin;
begin += sizeof(uint8_t);
algorithm_ = *begin;
begin += sizeof(uint8_t);
rdm_method_ = *begin;
begin += sizeof(uint8_t);
rdm_value_ = isc::util::readUint64(&(*begin), sizeof(uint64_t));
begin += sizeof(uint64_t);
auth_info_.erase(auth_info_.begin(), auth_info_.end());
std::for_each(begin, end, [this](uint8_t msgdata)
{ auth_info_.push_back(msgdata); });
}
std::string
Option6Auth::toText(int indent) const {
stringstream output;
std::string in(indent, ' '); //base indent
output << in << "protocol=" << static_cast<int>(protocol_)
<< ", algorithm=" << static_cast<int>(algorithm_)
<< ", rdm method=" << static_cast<int>(rdm_method_)
<< ", rdm value=" << rdm_value_
<< ", value=" << isc::util::encode::encodeHex(auth_info_);
2018-06-18 15:51:16 +02:00
return output.str();
}
} // end namespace dhcp
} // end namespace isc