123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223 |
- // Copyright (C) 2014 Internet Systems Consortium, Inc. ("ISC")
- //
- // Permission to use, copy, modify, and/or distribute this software for any
- // purpose with or without fee is hereby granted, provided that the above
- // copyright notice and this permission notice appear in all copies.
- //
- // THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH
- // REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
- // AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT,
- // INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
- // LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
- // OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
- // PERFORMANCE OF THIS SOFTWARE.
- #include <dhcpsrv/host.h>
- #include <util/strutil.h>
- #include <exceptions/exceptions.h>
- #include <sstream>
- namespace isc {
- namespace dhcp {
- IPv6Resrv::IPv6Resrv(const Type& type,
- const asiolink::IOAddress& prefix,
- const uint8_t prefix_len)
- : type_(type), prefix_(asiolink::IOAddress("::")), prefix_len_(128) {
- // Validate and set the actual values.
- set(type, prefix, prefix_len);
- }
- void
- IPv6Resrv::set(const Type& type, const asiolink::IOAddress& prefix,
- const uint8_t prefix_len) {
- if (!prefix.isV6() || prefix.isV6Multicast()) {
- isc_throw(isc::BadValue, "invalid prefix '" << prefix
- << "' for new IPv6 reservation");
- } else if (prefix_len > 128) {
- isc_throw(isc::BadValue, "invalid prefix length '"
- << static_cast<int>(prefix_len)
- << "' for new IPv6 reservation");
- } else if ((type == TYPE_NA) && (prefix_len != 128)) {
- isc_throw(isc::BadValue, "invalid prefix length '"
- << static_cast<int>(prefix_len)
- << "' for reserved IPv6 address, expected 128");
- }
- type_ = type;
- prefix_ = prefix;
- prefix_len_ = prefix_len;
- }
- std::string
- IPv6Resrv::toText() const {
- std::ostringstream s;
- s << prefix_;
- // For PD, append prefix length.
- if (getType() == TYPE_PD) {
- s << "/" << static_cast<int>(prefix_len_);
- }
- return (s.str());
- }
- bool
- IPv6Resrv::operator==(const IPv6Resrv& other) const {
- return (type_ == other.type_ &&
- prefix_ == other.prefix_ &&
- prefix_len_ == other.prefix_len_);
- }
- bool
- IPv6Resrv::operator!=(const IPv6Resrv& other) const {
- return (!operator==(other));
- }
- Host::Host(const uint8_t* identifier, const size_t identifier_len,
- const IdentifierType& identifier_type,
- const SubnetID ipv4_subnet_id, const SubnetID ipv6_subnet_id,
- const asiolink::IOAddress& ipv4_reservation,
- const std::string& hostname,
- const std::string& dhcp4_client_classes,
- const std::string& dhcp6_client_classes)
- : hw_address_(), duid_(), ipv4_subnet_id_(ipv4_subnet_id),
- ipv6_subnet_id_(ipv6_subnet_id),
- ipv4_reservation_(asiolink::IOAddress("0.0.0.0")),
- hostname_(hostname), dhcp4_client_classes_(dhcp4_client_classes),
- dhcp6_client_classes_(dhcp6_client_classes) {
- // Initialize HWAddr or DUID
- setIdentifier(identifier, identifier_len, identifier_type);
- // Validate and set IPv4 address reservation.
- setIPv4Reservation(ipv4_reservation);
- }
- Host::Host(const std::string& identifier, const std::string& identifier_name,
- const SubnetID ipv4_subnet_id, const SubnetID ipv6_subnet_id,
- const asiolink::IOAddress& ipv4_reservation,
- const std::string& hostname,
- const std::string& dhcp4_client_classes,
- const std::string& dhcp6_client_classes)
- : hw_address_(), duid_(), ipv4_subnet_id_(ipv4_subnet_id),
- ipv6_subnet_id_(ipv6_subnet_id),
- ipv4_reservation_(asiolink::IOAddress("0.0.0.0")),
- hostname_(hostname), dhcp4_client_classes_(dhcp4_client_classes),
- dhcp6_client_classes_(dhcp6_client_classes) {
- // Initialize HWAddr or DUID
- setIdentifier(identifier, identifier_name);
- // Validate and set IPv4 address reservation.
- setIPv4Reservation(ipv4_reservation);
- }
- const std::vector<uint8_t>&
- Host::getIdentifier() const {
- if (hw_address_) {
- return (hw_address_->hwaddr_);
- } else if (duid_) {
- return (duid_->getDuid());
- }
- static std::vector<uint8_t> empty_vector;
- return (empty_vector);
- }
- Host::IdentifierType
- Host::getIdentifierType() const {
- if (hw_address_) {
- return (IDENT_HWADDR);
- }
- return (IDENT_DUID);
- }
- void
- Host::setIdentifier(const uint8_t* identifier, const size_t len,
- const IdentifierType& type) {
- switch (type) {
- case IDENT_HWADDR:
- hw_address_ = HWAddrPtr(new HWAddr(identifier, len, HTYPE_ETHER));
- duid_.reset();
- break;
- case IDENT_DUID:
- duid_ = DuidPtr(new DUID(identifier, len));
- hw_address_.reset();
- break;
- default:
- isc_throw(isc::BadValue, "invalid client identifier type '"
- << static_cast<int>(type) << "' when creating host "
- " instance");
- }
- }
- void
- Host::setIdentifier(const std::string& identifier, const std::string& name) {
- if (name == "hw-address") {
- hw_address_ = HWAddrPtr(new HWAddr(HWAddr::fromText(identifier)));
- duid_.reset();
- } else if (name == "duid") {
- duid_ = DuidPtr(new DUID(DUID::fromText(identifier)));
- hw_address_.reset();
- } else {
- isc_throw(isc::BadValue, "invalid client identifier type '"
- << name << "' when creating host instance");
- }
- }
- void
- Host::setIPv4Reservation(const asiolink::IOAddress& address) {
- if (!address.isV4()) {
- isc_throw(isc::BadValue, "address '" << address << "' is not a valid"
- " IPv4 address");
- }
- ipv4_reservation_ = address;
- }
- void
- Host::addReservation(const IPv6Resrv& reservation) {
- // Check if it is not duplicating existing reservation.
- if (hasReservation(reservation)) {
- isc_throw(isc::InvalidOperation, "failed on attempt to add a duplicated"
- " host reservation for " << reservation.toText());
- }
- // Add it.
- ipv6_reservations_.insert(IPv6ResrvTuple(reservation.getType(),
- reservation));
- }
- IPv6ResrvRange
- Host::getIPv6Reservations(const IPv6Resrv::Type& type) const {
- return (ipv6_reservations_.equal_range(type));
- }
- bool
- Host::hasReservation(const IPv6Resrv& reservation) const {
- IPv6ResrvRange reservations = getIPv6Reservations(reservation.getType());
- if (std::distance(reservations.first, reservations.second) > 0) {
- for (IPv6ResrvIterator it = reservations.first;
- it != reservations.second; ++it) {
- if (it->second == reservation) {
- return (true);
- }
- }
- }
- // No matching reservations found.
- return (false);
- }
- void
- Host::addClientClassInternal(ClientClasses& classes,
- const std::string& class_name) {
- std::string trimmed = util::str::trim(class_name);
- if (!class_name.empty()) {
- classes.insert(ClientClass(class_name));
- }
- }
- } // end of namespace isc::dhcp
- } // end of namespace isc
|