Kea 3.3.3
host_cmds.cc
Go to the documentation of this file.
1// Copyright (C) 2017-2026 Internet Systems Consortium, Inc. ("ISC")
2//
3// This Source Code Form is subject to the terms of the Mozilla Public
4// License, v. 2.0. If a copy of the MPL was not distributed with this
5// file, You can obtain one at http://mozilla.org/MPL/2.0/.
6
7#include <config.h>
8
11#include <cc/data.h>
12#include <cc/simple_parser.h>
13#include <config/cmds_impl.h>
14#include <config/command_mgr.h>
15#include <dhcpsrv/cfg_hosts.h>
18#include <dhcpsrv/cfgmgr.h>
19#include <dhcpsrv/host_mgr.h>
20#include <dhcpsrv/subnet_id.h>
22#include <host_cmds/host_cmds.h>
24#include <util/encode/encode.h>
25#include <util/str.h>
26
27#include <sstream>
28#include <string>
29
30#include <boost/algorithm/string.hpp>
31#include <boost/foreach.hpp>
32
33#include <host_cmds_log.h>
34
35using namespace isc::dhcp;
36using namespace isc::data;
37using namespace isc::config;
38using namespace isc::asiolink;
39using namespace isc::hooks;
40using namespace std;
41
42namespace isc {
43namespace host_cmds {
44
46class HostCmdsImpl : private CmdsImpl {
47public:
48
51
54
64 class Parameters {
65 public:
66
69
72
75
79
81 std::vector<uint8_t> ident;
82
86
88 size_t page_limit;
89
92
94 uint64_t host_id;
95
97 std::string hostname;
98
102
110 };
111
112public:
113
121 int
123
131 int
133
142
150 int
152
160 int
162
170 int
172
180 int
182
190 int
192
200 int
202
203private:
204
213 Parameters getParameters(const ConstElementPtr& args);
214
223 Parameters getAllParameters(const ConstElementPtr& args);
224
233 Parameters getPageParameters(const ConstElementPtr& args);
234
243 Parameters getByHostnameParameters(const ConstElementPtr& args);
244
253 Parameters getByIdParameters(const ConstElementPtr& args);
254
263 Parameters getByAddressParameters(const ConstElementPtr& params);
264
269 HostMgrOperationTarget getOperationTarget(const ConstElementPtr& args);
270
282 void validateHostForSubnet4(SubnetID subnet_id, const IOAddress& address);
283
295 void validateHostForSubnet6(SubnetID subnet_id,
296 const std::vector<IOAddress>& addresses);
297
305 bool checkHost4(const ConstHostPtr& host);
306
314 bool checkHost6(const ConstHostPtr& host);
315
317 HostDataSourcePtr db_storage_;
318
320 uint16_t family_;
321};
322
324 // There are two ways we can store host reservations: either in configuration
325 // or in DB backends. The prime interface we provide - HostMgr class - does
326 // not allow storing hosts if alternate data source (DB backend) is not
327 // available. Therefore we need to check both. If available, we will store
328 // reservations in SQL data source. If not, we will *one day* be able to
329 // update the configuration, but it is not possible yet. Current configuration
330 // is retrieved as const pointer. We would need a way to clone current
331 // configuration to staging, add a host and then commit the change.
332 // We need to think this through as we don't want to go through the whole
333 // reconfiguration process when a new host is added.
334
335 // Try to get alternate storage.
336 db_storage_ = HostMgr::instance().getHostDataSource();
337
338 // Try to get the configuration storage. This will come in handy one day.
339 // cfg_storage_ = CfgMgr::instance().getCurrentCfg()->getCfgHosts();
340
341 family_ = CfgMgr::instance().getFamily();
342}
343
345 db_storage_.reset();
346}
347
348int
350 string txt = "(missing parameters)";
351 bool force_global(false);
352 try {
353 extractCommand(handle);
354 if (cmd_args_) {
355 txt = cmd_args_->str();
356 }
357
359 .arg(txt);
360
361 if (!cmd_args_) {
362 isc_throw(isc::BadValue, "no parameters specified for the command");
363 }
364
365 HostMgrOperationTarget operation_target = getOperationTarget(cmd_args_);
366 if (operation_target == HostMgrOperationTarget::UNSPECIFIED_SOURCE) {
368 }
369
370 ConstElementPtr reservation = cmd_args_->get("reservation");
371 if (!reservation) {
372 isc_throw(isc::BadValue, "reservation must be specified");
373 }
374
375 HostPtr host;
376 if (family_ == AF_INET) {
377 HostDataParser4 parser;
378 host = parser.parseWithSubnet(reservation, false);
379 force_global = checkHost4(host);
380 if (force_global) {
381 host->setIPv4SubnetID(SUBNET_ID_GLOBAL);
382 }
383 } else {
384 HostDataParser6 parser;
385 host = parser.parseWithSubnet(reservation, false);
386 force_global = checkHost6(host);
387 if (force_global) {
388 host->setIPv6SubnetID(SUBNET_ID_GLOBAL);
389 }
390 }
391
392 // If we haven't accessed db_storage_ yet, try to retrieve it.
393 if (!db_storage_) {
394 db_storage_ = HostMgr::instance().getHostDataSource();
395 }
396
397 if (!db_storage_ && operation_target == HostMgrOperationTarget::ALTERNATE_SOURCES) {
398 // If it's still not available, bail out.
399 isc_throw(isc::BadValue, "Host database not available, cannot add host.");
400 }
401
402 if (family_ == AF_INET) {
403 // Validate the IPv4 subnet id against configured subnet and also verify
404 // that the reserved IPv4 address (if non-zero) belongs to this subnet.
405 validateHostForSubnet4(host->getIPv4SubnetID(),
406 host->getIPv4Reservation());
407
408 } else {
409 // Retrieve all reserved addresses from the host. We're going to
410 // check if these addresses are in range with the specified subnet.
411 // If any of them is not in range, we will reject the command.
412 // Note that we do not validate delegated prefixes because they don't
413 // have to match the subnet prefix.
414 auto const& range = host->getIPv6Reservations(IPv6Resrv::TYPE_NA);
415 std::vector<IOAddress> addresses;
416 BOOST_FOREACH(auto const& address, range) {
417 addresses.push_back(address.second.getPrefix());
418 }
419 // Validate the IPv6 subnet id against configured subnet and also
420 // verify that the reserved IPv6 addresses (if any) belong to this
421 // subnet.
422 validateHostForSubnet6(host->getIPv6SubnetID(), addresses);
423 }
424
425 HostMgr::instance().add(host, operation_target);
426 } catch (const std::exception& ex) {
428 .arg(txt)
429 .arg(ex.what());
430 setErrorResponse(handle, ex.what());
431 return (1);
432 }
433
435 .arg(txt);
436 string msg("Host added.");
437 if (force_global) {
438 msg += " subnet-id not specified, assumed global (subnet-id 0).";
439 }
440 setSuccessResponse(handle, msg);
441 return (0);
442}
443
445HostCmdsImpl::getParameters(const ConstElementPtr& params) {
446 Parameters x;
447
448 if (!params || params->getType() != Element::map) {
449 isc_throw(BadValue, "Parameters missing or are not a map.");
450 }
451
452 // We support 2 types of reservation-get:
453 // reservation-get(subnet-id, address, operation-target)
454 // reservation-get(subnet-id, identifier-type, identifier, operation-target)
455 ConstElementPtr addr = params->get("ip-address");
456 ConstElementPtr type = params->get("identifier-type");
457 ConstElementPtr ident = params->get("identifier");
458 if (params->contains("subnet-id") || (!addr && !type && !ident)) {
459 int64_t value = data::SimpleParser::getInteger(params, "subnet-id",
460 0, dhcp::SUBNET_ID_MAX);
461 x.subnet_id = static_cast<SubnetID>(value);
462 x.has_subnet_id = true;
463 } else {
464 x.has_subnet_id = false;
465 }
466
467 x.operation_target = getOperationTarget(params);
468
469 if (addr) {
470 if (addr->getType() != Element::string) {
471 isc_throw(BadValue, "'ip-address' is not a string.");
472 }
473
474 x.addr = IOAddress(addr->stringValue());
475 x.query_by_addr = true;
476 if (!x.has_subnet_id) {
477 isc_throw(BadValue, "missing parameter 'subnet-id', use "
478 "'reservation-get-by-address' with 'ip-address' set to \""
479 << addr->stringValue() << "\" to get the list of "
480 << "reservations with this address");
481 }
482 return (x);
483 }
484
485 // No address specified. Ok, so it must be identifier based query.
486 // "identifier-type": "duid",
487 // "identifier": "aa:bb:cc:dd:ee:..."
488
489 if (!type || type->getType() != Element::string) {
490 isc_throw(BadValue, "No 'ip-address' provided"
491 " and 'identifier-type' is either missing or not a string.");
492 }
493 if (!ident || ident->getType() != Element::string) {
494 isc_throw(BadValue, "No 'ip-address' provided"
495 " and 'identifier' is either missing or not a string.");
496 }
497
498 // Got the parameters. Let's see if their values make sense.
499
500 // Try to parse the identifier value first.
501 try {
502 x.ident = util::str::quotedStringToBinary(ident->stringValue());
503 if (x.ident.empty()) {
504 util::str::decodeFormattedHexString(ident->stringValue(),
505 x.ident);
506 }
507 } catch (...) {
508 // The string doesn't match any known pattern, so we have to
509 // report an error at this point.
510 isc_throw(BadValue, "Unable to parse 'identifier' value.");
511 }
512
513 if (x.ident.empty()) {
514 isc_throw(BadValue, "Unable to query for empty 'identifier'.");
515 }
516
517 // Next, try to convert identifier-type
518 try {
519 x.type = Host::getIdentifierType(type->stringValue());
520 } catch (const std::exception& ex) {
521 isc_throw(BadValue, "Value of 'identifier-type' was not recognized.");
522 }
523
524 x.query_by_addr = false;
525 if (!x.has_subnet_id) {
526 isc_throw(BadValue, "missing parameter 'subnet-id', use "
527 "'reservation-get-by-id' with 'identifier-type' set to \""
528 << type->stringValue() << "\" and 'identifier' to \""
529 << ident->stringValue() << "\" to get the list of "
530 << "reservations with this identifier");
531 }
532 return (x);
533}
534
535void
536HostCmdsImpl::validateHostForSubnet4(SubnetID subnet_id, const IOAddress& address) {
537 if (subnet_id != 0) {
538 auto cfg = CfgMgr::instance().getCurrentCfg()->getCfgSubnets4();
539 auto subnet = cfg->getBySubnetId(subnet_id);
540 if (!subnet) {
541 isc_throw(isc::BadValue,
542 "IPv4 subnet with ID of '" << subnet_id
543 << "' is not configured");
544 }
545
546 if (!address.isV4Zero() && !address.isV6Zero()
547 && !subnet->inRange(address)) {
548 isc_throw(isc::BadValue,
549 "specified reservation '" << address
550 << "' is not matching the IPv4 subnet prefix '"
551 << subnet->toText() << "'");
552 }
553 }
554}
555
556void
557HostCmdsImpl::validateHostForSubnet6(SubnetID subnet_id,
558 const std::vector<IOAddress>& addresses) {
559 if (subnet_id != 0) {
560 auto cfg = CfgMgr::instance().getCurrentCfg()->getCfgSubnets6();
561 auto subnet = cfg->getBySubnetId(subnet_id);
562 if (!subnet) {
563 isc_throw(isc::BadValue,
564 "IPv6 subnet with ID of '" << subnet_id
565 << "' is not configured");
566 }
567
568 for (auto const& address : addresses) {
569 if (!subnet->inRange(address)) {
570 isc_throw(isc::BadValue,
571 "specified reservation '" << address
572 << "' is not matching the IPv6 subnet prefix '"
573 << subnet->toText() << "'");
574 }
575 }
576 }
577}
578
579bool
580HostCmdsImpl::checkHost4(const ConstHostPtr& host) {
581 if (host->getIPv4SubnetID() != SUBNET_ID_UNUSED) {
582 return (false);
583 }
584 const IOAddress& addr = host->getIPv4Reservation();
585 if (!addr.isV4Zero()) {
586 // Try to find a subnet hint.
587 auto subnets = CfgMgr::instance().getCurrentCfg()->getCfgSubnets4();
588 ConstSubnet4Ptr guarded;
589 ConstSubnet4Ptr candidate;
590 bool others = false;
591 for (auto const& subnet : *subnets->getAll()) {
592 if (!subnet->inRange(addr)) {
593 continue;
594 }
595 if (subnet->clientSupported(ClientClasses())) {
596 if (!candidate) {
597 candidate = subnet;
598 } else {
599 others = true;
600 }
601 } else if (!guarded) {
602 guarded = subnet;
603 } else {
604 others = true;
605 }
606 }
607 if (guarded && candidate) {
608 others = true;
609 }
610 if (!guarded && !candidate) {
611 isc_throw(isc::BadValue, "Mandatory 'subnet-id' parameter missing."
612 << " The address '" << addr.toText()
613 << "' belongs to no configured subnet.");
614 }
615 if (candidate) {
616 isc_throw(isc::BadValue, "Mandatory 'subnet-id' parameter missing."
617 << " The address '" << addr.toText()
618 << "' belongs to subnet '" << candidate->toText()
619 << "' id " << candidate->getID()
620 << (others ? " and others." : "."));
621 } else {
622 isc_throw(isc::BadValue, "Mandatory 'subnet-id' parameter missing."
623 << " The address '" << addr.toText()
624 << "' belongs to guarded subnet '" << guarded->toText()
625 << "' id " << guarded->getID()
626 << (others ? " and others." : "."));
627 }
628 } else {
629 return (true);
630 }
631}
632
633bool
634HostCmdsImpl::checkHost6(const ConstHostPtr& host) {
635 if (host->getIPv6SubnetID() != SUBNET_ID_UNUSED) {
636 return (false);
637 }
638 auto const& range = host->getIPv6Reservations();
639 std::vector<IOAddress> addresses;
640 bool has_prefixes = false;
641 BOOST_FOREACH(auto const& address, range) {
642 if (address.first == IPv6Resrv::TYPE_NA) {
643 addresses.push_back(address.second.getPrefix());
644 } else {
645 has_prefixes = true;
646 }
647 }
648 if (!addresses.empty()) {
649 // Try to find a subnet hint.
650 auto subnets = CfgMgr::instance().getCurrentCfg()->getCfgSubnets6();
651 ConstSubnet6Ptr guarded;
652 ConstSubnet6Ptr candidate;
653 bool others = false;
654 for (auto const& subnet : *subnets->getAll()) {
655 bool in_range = true;
656 for (auto const& address : addresses) {
657 if (!subnet->inRange(address)) {
658 in_range = false;
659 break;
660 }
661 }
662 if (!in_range) {
663 continue;
664 }
665 if (subnet->clientSupported(ClientClasses())) {
666 if (!candidate) {
667 candidate = subnet;
668 } else {
669 others = true;
670 }
671 } else if (!guarded) {
672 guarded = subnet;
673 } else {
674 others = true;
675 }
676 }
677 if (guarded && candidate) {
678 others = true;
679 }
680 if (!guarded && !candidate) {
681 isc_throw(isc::BadValue, "Mandatory 'subnet-id' parameter missing."
682 << " Reserved IPv6 addresses do not belong to a"
683 << " common configured subnet.");
684 }
685 if (candidate) {
686 isc_throw(isc::BadValue, "Mandatory 'subnet-id' parameter missing."
687 << " Reserved IPv6 addresses belong to subnet '"
688 << candidate->toText() << "' id " << candidate->getID()
689 << (others ? " and others." : "."));
690 } else {
691 isc_throw(isc::BadValue, "Mandatory 'subnet-id' parameter missing."
692 << " Reserved IPv6 addresses belong to guarded subnet '"
693 << guarded->toText() << "' id " << guarded->getID()
694 << (others ? " and others." : "."));
695 }
696 } else if (has_prefixes) {
697 isc_throw(isc::BadValue, "Mandatory 'subnet-id' parameter missing."
698 << " Prefixes are not attached to subnets so no hint is"
699 << " available.");
700 } else {
701 return (true);
702 }
703}
704
705int
707 string txt = "(missing parameters)";
708 Parameters p;
709 ElementPtr host_json;
710 try {
711 extractCommand(handle);
712 if (cmd_args_) {
713 txt = cmd_args_->str();
714 }
715
717 .arg(txt);
718
719 p = getParameters(cmd_args_);
720
723 }
724
725 ConstHostPtr host;
726 if (p.query_by_addr) {
727 // Query by address
728 if (p.addr.isV4()) {
730 } else {
732 }
733 } else {
734 // Query by identifier
735 if (family_ == AF_INET) {
736 host = HostMgr::instance().get4(p.subnet_id, p.type, &p.ident[0],
737 p.ident.size(), p.operation_target);
738 } else {
739 host = HostMgr::instance().get6(p.subnet_id, p.type, &p.ident[0],
740 p.ident.size(), p.operation_target);
741 }
742 }
743 if (host) {
744 SubnetID subnet_id;
745 if (family_ == AF_INET) {
746 host_json = host->toElement4();
747 subnet_id = host->getIPv4SubnetID();
748 } else {
749 host_json = host->toElement6();
750 subnet_id = host->getIPv6SubnetID();
751 }
752 host_json->set("subnet-id", Element::create(subnet_id));
753 }
754 } catch (const std::exception& ex) {
756 .arg(txt)
757 .arg(ex.what());
758 setErrorResponse(handle, ex.what());
759 return (1);
760 }
761
763 .arg(txt);
764
765 if (host_json) {
767 "Host found.", host_json);
768 setResponse(handle, response);
769 } else {
770 setErrorResponse(handle, "Host not found.", CONTROL_RESULT_EMPTY);
771 }
772
773 return (0);
774}
775
776int
778 string txt = "(missing parameters)";
779 Parameters p;
780 ElementPtr hosts_json = Element::createList();
781 try {
782 extractCommand(handle);
783 if (cmd_args_) {
784 txt = cmd_args_->str();
785 }
786
788 .arg(txt);
789
790 p = getByAddressParameters(cmd_args_);
791
794 }
795
797 if (p.has_subnet_id) {
798 if (family_ == AF_INET) {
799 validateHostForSubnet4(p.subnet_id,
802 } else {
803 validateHostForSubnet6(p.subnet_id, std::vector<IOAddress>());
805 }
806 } else {
807 if (family_ == AF_INET) {
809 } else {
811 }
812 }
813
814 // Add the subnet-id when it was not specified by the command
815 // parameters and filter out wrong universe entries.
816 SubnetID subnet_id = p.subnet_id;
817 ElementPtr host_json;
818 for (auto const& host : hosts) {
819 if (!p.has_subnet_id) {
820 if (family_ == AF_INET) {
821 subnet_id = host->getIPv4SubnetID();
822 } else {
823 subnet_id = host->getIPv6SubnetID();
824 }
825
826 if (subnet_id == SUBNET_ID_UNUSED) {
827 continue;
828 }
829 }
830
831 if (family_ == AF_INET) {
832 host_json = host->toElement4();
833 } else {
834 host_json = host->toElement6();
835 }
836
837 host_json->set("subnet-id", Element::create(subnet_id));
838 hosts_json->add(host_json);
839 }
840 } catch (const std::exception& ex) {
842 .arg(txt)
843 .arg(ex.what());
844 setErrorResponse(handle, ex.what());
845 return (1);
846 }
847
849 .arg(txt);
850
851 ostringstream msg;
852 msg << hosts_json->size()
853 << " IPv" << (family_ == AF_INET ? "4" : "6")
854 << " host(s) found.";
856 result->set("hosts", hosts_json);
857
858 ConstElementPtr response = createAnswer(hosts_json->size() > 0 ?
861 msg.str(), result);
862 setResponse(handle, response);
863
864 return (0);
865}
866
867int
869 string txt = "(missing parameters)";
870 Parameters p;
871 bool deleted;
872 try {
873 extractCommand(handle);
874 if (cmd_args_) {
875 txt = cmd_args_->str();
876 }
877
879 .arg(txt);
880
881 p = getParameters(cmd_args_);
884 }
885
886 if (p.query_by_addr) {
887 // try to delete by address
889 } else {
890 // try to delete by identifier
891 if (family_ == AF_INET) {
892 deleted = HostMgr::instance().del4(p.subnet_id, p.type,
893 &p.ident[0], p.ident.size(),
895 } else {
896 deleted = HostMgr::instance().del6(p.subnet_id, p.type,
897 &p.ident[0], p.ident.size(),
899 }
900 }
901 } catch (const std::exception& ex) {
903 .arg(txt)
904 .arg(ex.what());
905 setErrorResponse(handle, ex.what());
906 return (1);
907 }
908
910 .arg(txt);
911
912 if (deleted) {
913 setSuccessResponse(handle, "Host deleted.");
914 } else {
915 setErrorResponse(handle, "Host not deleted (not found).",
917 }
918
919 return (0);
920}
921
923HostCmdsImpl::getAllParameters(const ConstElementPtr& params) {
924 Parameters x;
925
926 if (!params || params->getType() != Element::map) {
927 isc_throw(BadValue, "Parameters missing or are not a map.");
928 }
929
930 // We support one type of reservation-get-all(subnet-id)
931 int64_t tmp = data::SimpleParser::getInteger(params, "subnet-id",
932 0, dhcp::SUBNET_ID_MAX);
933 x.subnet_id = static_cast<SubnetID>(tmp);
934 x.has_subnet_id = true;
935
936 x.operation_target = getOperationTarget(params);
937
938 return (x);
939}
940
941HostCmdsImpl::Parameters
942HostCmdsImpl::getPageParameters(const ConstElementPtr& params) {
943 Parameters x;
944
945 if (!params || params->getType() != Element::map) {
946 isc_throw(BadValue, "Parameters missing or are not a map.");
947 }
948
949 int64_t tmp = data::SimpleParser::getInteger(params, "limit", 0,
950 numeric_limits<uint32_t>::max());
951 x.page_limit = static_cast<size_t>(tmp);
952
953 // subnet-id, source-index and from host-id are optional.
954 if (params->contains("subnet-id")) {
955 tmp = data::SimpleParser::getInteger(params, "subnet-id",
956 0, dhcp::SUBNET_ID_MAX);
957 x.subnet_id = static_cast<SubnetID>(tmp);
958 x.has_subnet_id = true;
959 }
960
961 x.source_index = 0;
962 if (params->get("source-index")) {
963 tmp = data::SimpleParser::getInteger(params, "source-index", 0, 10);
964 x.source_index = static_cast<size_t>(tmp);
965 }
966
967 x.host_id = 0;
968 if (params->get("from")) {
969 tmp = data::SimpleParser::getInteger(params, "from");
970 x.host_id = static_cast<uint64_t>(tmp);
971 }
972
973 return (x);
974}
975
977HostCmdsImpl::getByHostnameParameters(const ConstElementPtr& params) {
978 Parameters x;
979
980 if (!params || params->getType() != Element::map) {
981 isc_throw(BadValue, "Parameters missing or are not a map.");
982 }
983
984 string hostname = data::SimpleParser::getString(params, "hostname");
985 x.hostname = hostname;
986
987 // subnet-id is optional.
988 if (params->contains("subnet-id")) {
989 int64_t tmp = data::SimpleParser::getInteger(params, "subnet-id",
990 0, dhcp::SUBNET_ID_MAX);
991 x.subnet_id = static_cast<SubnetID>(tmp);
992 x.has_subnet_id = true;
993 }
994
995 x.operation_target = getOperationTarget(params);
996
997 return (x);
998}
999
1001HostCmdsImpl::getByIdParameters(const ConstElementPtr& params) {
1002 Parameters x;
1003
1004 if (!params || params->getType() != Element::map) {
1005 isc_throw(BadValue, "Parameters missing or are not a map.");
1006 }
1007
1008 ConstElementPtr type = params->get("identifier-type");
1009 ConstElementPtr ident = params->get("identifier");
1010 if (!type || type->getType() != Element::string) {
1011 isc_throw(BadValue, "'identifier-type' is either missing"
1012 " or not a string.");
1013 }
1014 if (!ident || ident->getType() != Element::string) {
1015 isc_throw(BadValue, "'identifier' is either missing or not a string.");
1016 }
1017
1018 // subnet-id is forbidden.
1019 if (params->contains("subnet-id")) {
1020 isc_throw(BadValue, "'subnet-id' is forbidden in reservation-get-by-id");
1021 }
1022
1023 // Got the parameters. Let's see if their values make sense.
1024
1025 // Try to parse the identifier value first.
1026 try {
1027 x.ident = util::str::quotedStringToBinary(ident->stringValue());
1028 if (x.ident.empty()) {
1029 util::str::decodeFormattedHexString(ident->stringValue(),
1030 x.ident);
1031 }
1032 } catch (...) {
1033 // The string doesn't match any known pattern, so we have to
1034 // report an error at this point.
1035 isc_throw(BadValue, "Unable to parse 'identifier' value.");
1036 }
1037
1038 if (x.ident.empty()) {
1039 isc_throw(BadValue, "Unable to query for empty 'identifier'.");
1040 }
1041
1042 // Next, try to convert identifier-type
1043 try {
1044 x.type = Host::getIdentifierType(type->stringValue());
1045 } catch (const std::exception& ex) {
1046 isc_throw(BadValue, "Value of 'identifier-type' was not recognized.");
1047 }
1048
1049 x.operation_target = getOperationTarget(params);
1050
1051 return (x);
1052}
1053
1055HostCmdsImpl::getByAddressParameters(const ConstElementPtr& params) {
1056 Parameters x;
1057
1058 if (!params || params->getType() != Element::map) {
1059 isc_throw(BadValue, "Parameters missing or are not a map.");
1060 }
1061
1062 // We support 1 type of reservation-get-by-address:
1063 // reservation-get-by-address(subnet-id, address, operation-target)
1064 // where subnet-id and operation-target are optional
1065 IOAddress addr = data::SimpleParser::getAddress(params, "ip-address");
1066 if (!addr.isV4() && !addr.isV6()) {
1067 isc_throw(BadValue, "Failed to parse IP address " << addr);
1068 }
1069
1070 x.addr = addr;
1071 x.query_by_addr = true;
1072
1073 if (params->contains("subnet-id")) {
1074 int64_t tmp = data::SimpleParser::getInteger(params, "subnet-id",
1075 0, dhcp::SUBNET_ID_MAX);
1076 x.subnet_id = static_cast<SubnetID>(tmp);
1077 x.has_subnet_id = true;
1078 }
1079
1080 x.operation_target = getOperationTarget(params);
1081
1082 return (x);
1083}
1084
1086HostCmdsImpl::getOperationTarget(const ConstElementPtr& args) {
1087 // Operation target is optional.
1088 if (!args->get("operation-target")) {
1089 return HostMgrOperationTarget::UNSPECIFIED_SOURCE;
1090 }
1091
1092 std::string raw = data::SimpleParser::getString(args, "operation-target");
1093
1094 if (raw == "memory") {
1095 return HostMgrOperationTarget::PRIMARY_SOURCE;
1096 } else if (raw == "database") {
1097 return HostMgrOperationTarget::ALTERNATE_SOURCES;
1098 } else if (raw == "all") {
1099 return HostMgrOperationTarget::ALL_SOURCES;
1100 } else if (raw == "default") {
1101 return HostMgrOperationTarget::UNSPECIFIED_SOURCE;
1102 } else {
1103 isc_throw(BadValue,
1104 "The 'operation-target' value (" << raw
1105 << ") is not within expected set: (memory, database, all, "
1106 << "default)");
1107 }
1108}
1109
1110int
1112 string txt = "(missing parameters)";
1113 Parameters p;
1114 ElementPtr hosts_json = Element::createList();
1115 try {
1116 extractCommand(handle);
1117 if (cmd_args_) {
1118 txt = cmd_args_->str();
1119 }
1120
1122 .arg(txt);
1123
1124 p = getAllParameters(cmd_args_);
1127 }
1128
1129 ConstHostCollection hosts;
1130 if (family_ == AF_INET) {
1131 validateHostForSubnet4(p.subnet_id,
1134 } else {
1135 validateHostForSubnet6(p.subnet_id, std::vector<IOAddress>());
1137 }
1138 for (auto const& host : hosts) {
1139 ElementPtr host_json;
1140 if (family_ == AF_INET) {
1141 host_json = host->toElement4();
1142 SubnetID subnet_id = host->getIPv4SubnetID();
1143 host_json->set("subnet-id", Element::create(subnet_id));
1144 } else {
1145 host_json = host->toElement6();
1146 SubnetID subnet_id = host->getIPv6SubnetID();
1147 host_json->set("subnet-id", Element::create(subnet_id));
1148 }
1149 hosts_json->add(host_json);
1150 }
1151 } catch (const std::exception& ex) {
1153 .arg(txt)
1154 .arg(ex.what());
1155 setErrorResponse(handle, ex.what());
1156 return (1);
1157 }
1158
1160 .arg(txt);
1161
1162 ostringstream msg;
1163 msg << hosts_json->size()
1164 << " IPv" << (family_ == AF_INET ? "4" : "6")
1165 << " host(s) found.";
1166 ElementPtr result = Element::createMap();
1167 result->set("hosts", hosts_json);
1168
1169 ConstElementPtr response = createAnswer(hosts_json->size() > 0 ?
1172 msg.str(), result);
1173 setResponse(handle, response);
1174
1175 return (0);
1176}
1177
1178int
1180 string txt = "(missing parameters)";
1181 Parameters p;
1182 size_t idx;
1183 ElementPtr hosts_json = Element::createList();
1184 uint64_t last_id(0);
1185 try {
1186 extractCommand(handle);
1187 if (cmd_args_) {
1188 txt = cmd_args_->str();
1189 }
1190
1192 .arg(txt);
1193
1194 p = getPageParameters(cmd_args_);
1195 idx = p.source_index;
1196 HostPageSize page_size(p.page_limit);
1197 ConstHostCollection hosts;
1198 if (p.has_subnet_id) {
1199 if (family_ == AF_INET) {
1200 validateHostForSubnet4(p.subnet_id,
1202 hosts = HostMgr::instance().getPage4(p.subnet_id, idx,
1203 p.host_id, page_size);
1204 } else {
1205 validateHostForSubnet6(p.subnet_id, std::vector<IOAddress>());
1206 hosts = HostMgr::instance().getPage6(p.subnet_id, idx,
1207 p.host_id, page_size);
1208 }
1209 } else {
1210 if (family_ == AF_INET) {
1211 hosts = HostMgr::instance().getPage4(idx, p.host_id, page_size);
1212 } else {
1213 hosts = HostMgr::instance().getPage6(idx, p.host_id, page_size);
1214 }
1215 }
1216 SubnetID subnet_id = p.subnet_id;
1217 ElementPtr host_json;
1218 for (auto const& host : hosts) {
1219 if (!p.has_subnet_id) {
1220 if (family_ == AF_INET) {
1221 subnet_id = host->getIPv4SubnetID();
1222 } else {
1223 subnet_id = host->getIPv6SubnetID();
1224 }
1225 if (subnet_id == SUBNET_ID_UNUSED) {
1226 continue;
1227 }
1228 }
1229 if (family_ == AF_INET) {
1230 host_json = host->toElement4();
1231 } else {
1232 host_json = host->toElement6();
1233 }
1234 host_json->set("subnet-id", Element::create(subnet_id));
1235 hosts_json->add(host_json);
1236 last_id = host->getHostId();
1237 }
1238 } catch (const std::exception& ex) {
1240 .arg(txt)
1241 .arg(ex.what());
1242 setErrorResponse(handle, ex.what());
1243 return (1);
1244 }
1245
1247 .arg(txt);
1248
1249 ostringstream msg;
1250 msg << hosts_json->size()
1251 << " IPv" << (family_ == AF_INET ? "4" : "6")
1252 << " host(s) found.";
1253 ElementPtr result = Element::createMap();
1254 result->set("hosts", hosts_json);
1255 result->set("count",
1256 Element::create(static_cast<int64_t>(hosts_json->size())));
1257 if (hosts_json->size() > 0) {
1259 next->set("source-index",
1260 Element::create(static_cast<int64_t>(idx)));
1261 next->set("from", Element::create(static_cast<int64_t>(last_id)));
1262 result->set("next", next);
1263 }
1264
1265 ConstElementPtr response = createAnswer(hosts_json->size() > 0 ?
1268 msg.str(), result);
1269 setResponse(handle, response);
1270
1271 return (0);
1272}
1273
1274int
1276 string txt = "(missing parameters)";
1277 Parameters p;
1278 ElementPtr hosts_json = Element::createList();
1279 try {
1280 extractCommand(handle);
1281 if (cmd_args_) {
1282 txt = cmd_args_->str();
1283 }
1284
1286 .arg(txt);
1287
1288 p = getByHostnameParameters(cmd_args_);
1291 }
1292
1293 string hostname = p.hostname;
1294 if (hostname.empty()) {
1295 isc_throw(isc::BadValue, "Empty hostname");
1296 }
1297 boost::algorithm::to_lower(hostname);
1298 ConstHostCollection hosts;
1299 if (p.has_subnet_id) {
1300 if (family_ == AF_INET) {
1301 validateHostForSubnet4(p.subnet_id,
1303 hosts = HostMgr::instance().getAllbyHostname4(hostname,
1304 p.subnet_id,
1306 } else {
1307 validateHostForSubnet6(p.subnet_id, std::vector<IOAddress>());
1308 hosts = HostMgr::instance().getAllbyHostname6(hostname,
1309 p.subnet_id,
1311 }
1312 } else {
1314 }
1315
1316 // Add the subnet-id when it was not specified by the command
1317 // parameters and filter out wrong universe entries.
1318 SubnetID subnet_id = p.subnet_id;
1319 ElementPtr host_json;
1320 for (auto const& host : hosts) {
1321 if (!p.has_subnet_id) {
1322 if (family_ == AF_INET) {
1323 subnet_id = host->getIPv4SubnetID();
1324 } else {
1325 subnet_id = host->getIPv6SubnetID();
1326 }
1327 if (subnet_id == SUBNET_ID_UNUSED) {
1328 continue;
1329 }
1330 }
1331 if (family_ == AF_INET) {
1332 host_json = host->toElement4();
1333 } else {
1334 host_json = host->toElement6();
1335 }
1336 host_json->set("subnet-id", Element::create(subnet_id));
1337 hosts_json->add(host_json);
1338 }
1339 } catch (const std::exception& ex) {
1341 .arg(txt)
1342 .arg(ex.what());
1343 setErrorResponse(handle, ex.what());
1344 return (1);
1345 }
1346
1348 .arg(txt);
1349
1350 ostringstream msg;
1351 msg << hosts_json->size()
1352 << " IPv" << (family_ == AF_INET ? "4" : "6")
1353 << " host(s) found.";
1354 ElementPtr result = Element::createMap();
1355 result->set("hosts", hosts_json);
1356
1357 ConstElementPtr response = createAnswer(hosts_json->size() > 0 ?
1360 msg.str(), result);
1361 setResponse(handle, response);
1362
1363 return (0);
1364}
1365
1366int
1368 string txt = "(missing parameters)";
1369 Parameters p;
1370 ElementPtr hosts_json = Element::createList();
1371 try {
1372 extractCommand(handle);
1373 if (cmd_args_) {
1374 txt = cmd_args_->str();
1375 }
1376
1378 .arg(txt);
1379
1380 p = getByIdParameters(cmd_args_);
1383 }
1384
1385 ConstHostCollection hosts;
1386 hosts = HostMgr::instance().getAll(p.type, &p.ident[0], p.ident.size(),
1388 SubnetID subnet_id;
1389 ElementPtr host_json;
1390 for (auto const& host : hosts) {
1391 if (family_ == AF_INET) {
1392 subnet_id = host->getIPv4SubnetID();
1393 } else {
1394 subnet_id = host->getIPv6SubnetID();
1395 }
1396 if (subnet_id == SUBNET_ID_UNUSED) {
1397 continue;
1398 }
1399 if (family_ == AF_INET) {
1400 host_json = host->toElement4();
1401 } else {
1402 host_json = host->toElement6();
1403 }
1404 host_json->set("subnet-id", Element::create(subnet_id));
1405 hosts_json->add(host_json);
1406 }
1407 } catch (const std::exception& ex) {
1409 .arg(txt)
1410 .arg(ex.what());
1411 setErrorResponse(handle, ex.what());
1412 return (1);
1413 }
1414
1416 .arg(txt);
1417
1418 ostringstream msg;
1419 msg << hosts_json->size()
1420 << " IPv" << (family_ == AF_INET ? "4" : "6")
1421 << " host(s) found.";
1422 ElementPtr result = Element::createMap();
1423 result->set("hosts", hosts_json);
1424
1425 ConstElementPtr response = createAnswer(hosts_json->size() > 0 ?
1428 msg.str(), result);
1429 setResponse(handle, response);
1430
1431 return (0);
1432}
1433
1434int
1436 string parameters("(missing parameters)");
1437 try {
1438 // Basic command extraction
1439 extractCommand(handle);
1440 if (cmd_args_) {
1441 parameters = cmd_args_->str();
1442 }
1443
1445 .arg(parameters);
1446
1447 // Sanity checks
1448 if (!cmd_args_) {
1450 "invalid command: does not contain mandatory '" << CONTROL_ARGUMENTS << "'");
1451 }
1452 if (cmd_args_->getType() != Element::map) {
1453 isc_throw(BadValue, "invalid command: expected '"
1454 << CONTROL_ARGUMENTS << "' to be a map, got "
1455 << Element::typeToName(cmd_args_->getType()) << " instead");
1456 }
1457 ConstElementPtr const reservation(cmd_args_->get("reservation"));
1458 if (!reservation) {
1459 isc_throw(BadValue, "invalid command: expected 'reservation' as the sole parameter "
1460 "inside the 'arguments' map, didn't get it instead");
1461 }
1462 if (reservation->getType() != Element::map) {
1463 isc_throw(BadValue, "invalid command: expected 'reservation' to be a map, got "
1464 << Element::typeToName(reservation->getType()) << " instead");
1465 }
1466
1467 HostMgrOperationTarget operation_target = getOperationTarget(cmd_args_);
1468 if (operation_target == HostMgrOperationTarget::UNSPECIFIED_SOURCE) {
1470 }
1471
1472 // Parse host-specific parameters.
1473 HostPtr host;
1474 if (family_ == AF_INET) {
1475 HostDataParser4 parser;
1476 host = parser.parseWithSubnet(reservation);
1477 } else {
1478 HostDataParser6 parser;
1479 host = parser.parseWithSubnet(reservation);
1480 }
1481
1482 // If db_storage_ was not accessed yet, try to retrieve it.
1483 if (!db_storage_) {
1484 db_storage_ = HostMgr::instance().getHostDataSource();
1485 }
1486
1487 if (!db_storage_ && operation_target == HostMgrOperationTarget::ALTERNATE_SOURCES) {
1488 // If it's still not available, bail out.
1489 isc_throw(BadValue, "host database not available, cannot update host");
1490 }
1491
1492 if (family_ == AF_INET) {
1493 // Validate the IPv4 subnet id against configured subnet and also verify
1494 // that the reserved IPv4 address (if non-zero) belongs to this subnet.
1495 validateHostForSubnet4(host->getIPv4SubnetID(),
1496 host->getIPv4Reservation());
1497
1498 } else {
1499 // Retrieve all reserved addresses from the host. We're going to
1500 // check if these addresses are in range with the specified subnet.
1501 // If any of them is not in range, we will reject the command.
1502 // Note that we do not validate delegated prefixes because they don't
1503 // have to match the subnet prefix.
1504 auto const& range = host->getIPv6Reservations(IPv6Resrv::TYPE_NA);
1505 std::vector<IOAddress> addresses;
1506 BOOST_FOREACH(auto const& address, range) {
1507 addresses.push_back(address.second.getPrefix());
1508 }
1509 // Validate the IPv6 subnet id against configured subnet and also
1510 // verify that the reserved IPv6 addresses (if any) belong to this
1511 // subnet.
1512 validateHostForSubnet6(host->getIPv6SubnetID(), addresses);
1513 }
1514
1515 // Do the update.
1516 HostMgr::instance().update(host, operation_target);
1517 } catch (exception const& exception) {
1519 .arg(parameters)
1520 .arg(exception.what());
1521 setErrorResponse(handle, exception.what());
1522 return (1);
1523 }
1524
1526 setSuccessResponse(handle, "Host updated.");
1527
1528 return (0);
1529}
1530
1532 :impl_(new HostCmdsImpl()) {
1533}
1534
1535int
1537 return (impl_->reservationAddHandler(handle));
1538}
1539
1540int
1542 return (impl_->reservationGetHandler(handle));
1543}
1544
1545int
1547 return (impl_->reservationDelHandler(handle));
1548}
1549
1550int
1552 return (impl_->reservationGetAllHandler(handle));
1553}
1554
1555int
1557 return (impl_->reservationGetPageHandler(handle));
1558}
1559
1560int
1562 return (impl_->reservationGetByHostnameHandler(handle));
1563}
1564
1565int
1567 return (impl_->reservationGetByIdHandler(handle));
1568}
1569
1570int
1572 return (impl_->reservationUpdateHandler(handle));
1573}
1574
1575int
1577 return (impl_->reservationGetByAddressHandler(handle));
1578}
1579
1580} // namespace host_cmds
1581} // namespace isc
static ElementPtr create(const Position &pos=ZERO_POSITION())
Create a NullElement.
Definition data.cc:300
static std::string typeToName(Element::types type)
Returns the name of the given type as a string.
Definition data.cc:716
@ map
Definition data.h:160
@ string
Definition data.h:157
static ElementPtr createMap(const Position &pos=ZERO_POSITION())
Creates an empty MapElement type ElementPtr.
Definition data.cc:355
static ElementPtr createList(const Position &pos=ZERO_POSITION())
Creates an empty ListElement type ElementPtr.
Definition data.cc:350
A generic exception that is thrown if a parameter given to a method is considered invalid in that con...
Base class that command handler implementers may use for common tasks.
Definition cmds_impl.h:21
void setErrorResponse(hooks::CalloutHandle &handle, const std::string &text, int status=CONTROL_RESULT_ERROR)
Set the callout argument "response" to indicate an error.
Definition cmds_impl.h:54
data::ConstElementPtr cmd_args_
Stores the command arguments extracted by a call to extractCommand.
Definition cmds_impl.h:72
void extractCommand(hooks::CalloutHandle &handle)
Extracts the command name and arguments from a Callout handle.
Definition cmds_impl.h:29
void setSuccessResponse(hooks::CalloutHandle &handle, const std::string &text)
Set the callout argument "response" to indicate success.
Definition cmds_impl.h:43
void setResponse(hooks::CalloutHandle &handle, data::ConstElementPtr &response)
Set the callout argument "response" to the given response.
Definition cmds_impl.h:64
static isc::asiolink::IOAddress getAddress(const ConstElementPtr &scope, const std::string &name)
Returns a IOAddress parameter from a scope.
static std::string getString(isc::data::ConstElementPtr scope, const std::string &name)
Returns a string parameter from a scope.
static int64_t getInteger(isc::data::ConstElementPtr scope, const std::string &name)
Returns an integer parameter from a scope.
uint16_t getFamily() const
Returns address family.
Definition cfgmgr.h:246
static CfgMgr & instance()
returns a single instance of Configuration Manager
Definition cfgmgr.cc:29
SrvConfigPtr getCurrentCfg()
Returns a pointer to the current configuration.
Definition cfgmgr.cc:116
ConstHostCollection getAll6(const SubnetID &subnet_id, const HostMgrOperationTarget target) const
Return all hosts in a DHCPv6 subnet.
Definition host_mgr.cc:171
ConstHostCollection getAll4(const SubnetID &subnet_id, const HostMgrOperationTarget target) const
Return all hosts in a DHCPv4 subnet.
Definition host_mgr.cc:151
virtual ConstHostCollection getPage6(const SubnetID &subnet_id, size_t &source_index, uint64_t lower_host_id, const HostPageSize &page_size) const
Returns range of hosts in a DHCPv6 subnet.
Definition host_mgr.cc:290
ConstHostCollection getAllbyHostname4(const std::string &hostname, const SubnetID &subnet_id, const HostMgrOperationTarget target) const
Return all hosts with a hostname in a DHCPv4 subnet.
Definition host_mgr.cc:211
bool del4(const SubnetID &subnet_id, const Host::IdentifierType &identifier_type, const uint8_t *identifier_begin, const size_t identifier_len, const HostMgrOperationTarget target)
Attempts to delete a host by (subnet4-id, identifier, identifier-type, operation-target).
Definition host_mgr.cc:824
ConstHostCollection getAll(const Host::IdentifierType &identifier_type, const uint8_t *identifier_begin, const size_t identifier_len, const HostMgrOperationTarget target) const
Return all hosts connected to any subnet for which reservations have been made using a specified iden...
Definition host_mgr.cc:123
bool del6(const SubnetID &subnet_id, const Host::IdentifierType &identifier_type, const uint8_t *identifier_begin, const size_t identifier_len, const HostMgrOperationTarget target)
Attempts to delete a host by (subnet6-id, identifier, identifier-type, operation-target).
Definition host_mgr.cc:861
void add(const HostPtr &host, const HostMgrOperationTarget target)
Adds a new host to the alternate data source.
Definition host_mgr.cc:764
bool del(const SubnetID &subnet_id, const asiolink::IOAddress &addr, const HostMgrOperationTarget target)
Attempts to delete hosts by address.
Definition host_mgr.cc:794
ConstHostCollection getAllbyHostname6(const std::string &hostname, const SubnetID &subnet_id, const HostMgrOperationTarget target) const
Return all hosts with a hostname in a DHCPv6 subnet.
Definition host_mgr.cc:235
virtual ConstHostCollection getPage4(const SubnetID &subnet_id, size_t &source_index, uint64_t lower_host_id, const HostPageSize &page_size) const
Returns range of hosts in a DHCPv4 subnet.
Definition host_mgr.cc:259
HostDataSourcePtr getHostDataSource() const
Returns the first host data source.
Definition host_mgr.cc:84
static HostMgr & instance()
Returns a sole instance of the HostMgr.
Definition host_mgr.cc:114
void update(HostPtr const &host, const HostMgrOperationTarget target)
Implements BaseHostDataSource::update() for alternate sources.
Definition host_mgr.cc:898
ConstHostCollection getAllbyHostname(const std::string &hostname, const HostMgrOperationTarget target) const
Return all hosts with a hostname.
Definition host_mgr.cc:191
ConstHostPtr get4(const SubnetID &subnet_id, const Host::IdentifierType &identifier_type, const uint8_t *identifier_begin, const size_t identifier_len, const HostMgrOperationTarget target) const
Returns a host connected to the IPv4 subnet.
Definition host_mgr.cc:465
ConstHostPtr get6(const SubnetID &subnet_id, const Host::IdentifierType &identifier_type, const uint8_t *identifier_begin, const size_t identifier_len, const HostMgrOperationTarget target) const
Returns a host connected to the IPv6 subnet.
Definition host_mgr.cc:650
Wraps value holding size of the page with host reservations.
Represents a device with IPv4 and/or IPv6 reservations.
Definition host.h:330
IdentifierType getIdentifierType() const
Returns the identifier type.
Definition host.cc:280
IdentifierType
Type of the host identifier.
Definition host.h:340
Per-packet callout handle.
Parameters specified for reservation-get and reservation-del.
Definition host_cmds.cc:64
HostMgrOperationTarget operation_target
Specifies the target host source (default UNSPECIFIED_SOURCE which means the default host source is c...
Definition host_cmds.cc:101
std::string hostname
Specifies host name (default "").
Definition host_cmds.cc:97
uint64_t host_id
Specifies host identifier (default 0).
Definition host_cmds.cc:94
std::vector< uint8_t > ident
Specifies identifier value (used when query_by_addr is false).
Definition host_cmds.cc:81
SubnetID subnet_id
Specifies subnet-id.
Definition host_cmds.cc:68
bool query_by_addr
Specifies parameter types (true = query by address, false = query by identifier-type,...
Definition host_cmds.cc:85
size_t source_index
Specifies source index (default 0).
Definition host_cmds.cc:91
Host::IdentifierType type
Specifies identifier type (usually FLEX_ID, used when query_by_addr is false).
Definition host_cmds.cc:78
IOAddress addr
Specifies IPv4 or IPv6 address (used when query_by_addr is true).
Definition host_cmds.cc:74
bool has_subnet_id
Specifies if subnet-id is present.
Definition host_cmds.cc:71
size_t page_limit
Specifies page limit (no default).
Definition host_cmds.cc:88
Wrapper class around reservation command handlers.
Definition host_cmds.cc:46
int reservationGetAllHandler(CalloutHandle &handle)
reservation-get-all command handler
int reservationAddHandler(CalloutHandle &handle)
reservation-add command handler
Definition host_cmds.cc:349
int reservationGetPageHandler(CalloutHandle &handle)
reservation-get-page command handler
int reservationGetHandler(CalloutHandle &handle)
reservation-get command handler
Definition host_cmds.cc:706
int reservationUpdateHandler(CalloutHandle &handle)
reservation-update command handler
int reservationGetByHostnameHandler(CalloutHandle &handle)
reservation-get-by-hostname command handler
int reservationDelHandler(CalloutHandle &handle)
reservation-del command handler
Definition host_cmds.cc:868
int reservationGetByAddressHandler(CalloutHandle &handle)
reservation-get-by-address command handler
Definition host_cmds.cc:777
int reservationGetByIdHandler(CalloutHandle &handle)
reservation-get-by-id command handler
int reservationGetPageHandler(hooks::CalloutHandle &handle)
reservation-get-page command handler
int reservationGetAllHandler(hooks::CalloutHandle &handle)
reservation-get-all command handler
int reservationGetByAddressHandler(hooks::CalloutHandle &handle)
reservation-get-by-address command handler
int reservationGetByHostnameHandler(hooks::CalloutHandle &handle)
reservation-get-by-hostname command handler
int reservationUpdateHandler(hooks::CalloutHandle &handle)
reservation-update command handler
int reservationGetHandler(hooks::CalloutHandle &handle)
reservation-get command handler
int reservationAddHandler(hooks::CalloutHandle &handle)
reservation-add command handler
int reservationDelHandler(hooks::CalloutHandle &handle)
reservation-del command handler
int reservationGetByIdHandler(hooks::CalloutHandle &handle)
reservation-get-by-id command handler
isc::dhcp::HostPtr parseWithSubnet(isc::data::ConstElementPtr host_data, bool required=true)
Parser specified parameter as host reservation data.
This file contains several functions and constants that are used for handling commands and responses ...
#define isc_throw(type, stream)
A shortcut macro to insert known values into exception arguments.
const isc::log::MessageID HOST_CMDS_RESERV_UPDATE
const isc::log::MessageID HOST_CMDS_RESERV_GET_ALL_FAILED
const isc::log::MessageID HOST_CMDS_RESERV_ADD
const isc::log::MessageID HOST_CMDS_RESERV_GET_PAGE
const isc::log::MessageID HOST_CMDS_RESERV_GET_BY_HOSTNAME_SUCCESS
const isc::log::MessageID HOST_CMDS_RESERV_DEL_FAILED
const isc::log::MessageID HOST_CMDS_RESERV_ADD_SUCCESS
const isc::log::MessageID HOST_CMDS_RESERV_GET_BY_ID
const isc::log::MessageID HOST_CMDS_RESERV_GET_BY_ADDRESS_FAILED
const isc::log::MessageID HOST_CMDS_RESERV_GET_PAGE_SUCCESS
const isc::log::MessageID HOST_CMDS_RESERV_GET
const isc::log::MessageID HOST_CMDS_RESERV_DEL
const isc::log::MessageID HOST_CMDS_RESERV_UPDATE_FAILED
const isc::log::MessageID HOST_CMDS_RESERV_GET_PAGE_FAILED
const isc::log::MessageID HOST_CMDS_RESERV_GET_BY_ID_FAILED
const isc::log::MessageID HOST_CMDS_RESERV_GET_BY_ADDRESS_SUCCESS
const isc::log::MessageID HOST_CMDS_RESERV_GET_ALL_SUCCESS
const isc::log::MessageID HOST_CMDS_RESERV_UPDATE_SUCCESS
const isc::log::MessageID HOST_CMDS_RESERV_GET_ALL
const isc::log::MessageID HOST_CMDS_RESERV_DEL_SUCCESS
const isc::log::MessageID HOST_CMDS_RESERV_GET_BY_HOSTNAME_FAILED
const isc::log::MessageID HOST_CMDS_RESERV_GET_BY_ID_SUCCESS
const isc::log::MessageID HOST_CMDS_RESERV_ADD_FAILED
const isc::log::MessageID HOST_CMDS_RESERV_GET_SUCCESS
const isc::log::MessageID HOST_CMDS_RESERV_GET_FAILED
const isc::log::MessageID HOST_CMDS_RESERV_GET_BY_HOSTNAME
const isc::log::MessageID HOST_CMDS_RESERV_GET_BY_ADDRESS
#define LOG_ERROR(LOGGER, MESSAGE)
Macro to conveniently test error output and log it.
Definition macros.h:32
#define LOG_INFO(LOGGER, MESSAGE)
Macro to conveniently test info output and log it.
Definition macros.h:20
const char * CONTROL_ARGUMENTS
String used for arguments map ("arguments").
const int CONTROL_RESULT_EMPTY
Status code indicating that the specified command was completed correctly, but failed to produce any ...
ConstElementPtr createAnswer()
Creates a standard config/command level success answer message (i.e.
const int CONTROL_RESULT_SUCCESS
Status code indicating a successful operation.
boost::shared_ptr< const Element > ConstElementPtr
Definition data.h:30
boost::shared_ptr< Element > ElementPtr
Definition data.h:29
boost::shared_ptr< BaseHostDataSource > HostDataSourcePtr
HostDataSource pointer.
HostMgrOperationTarget
Definition host_mgr.h:27
@ ALTERNATE_SOURCES
Definition host_mgr.h:33
@ UNSPECIFIED_SOURCE
Definition host_mgr.h:29
@ ALL_SOURCES
Definition host_mgr.h:35
boost::shared_ptr< const Subnet6 > ConstSubnet6Ptr
A const pointer to a Subnet6 object.
Definition subnet.h:620
boost::shared_ptr< Host > HostPtr
Pointer to the Host object.
Definition host.h:840
std::vector< ConstHostPtr > ConstHostCollection
Collection of the const Host objects.
Definition host.h:846
boost::shared_ptr< const Subnet4 > ConstSubnet4Ptr
A const pointer to a Subnet4 object.
Definition subnet.h:455
uint32_t SubnetID
Defines unique IPv4 or IPv6 subnet identifier.
Definition subnet_id.h:25
boost::shared_ptr< const Host > ConstHostPtr
Const pointer to the Host object.
Definition host.h:843
isc::log::Logger host_cmds_logger("host-cmds-hooks")
HostDataParser< isc::dhcp::HostReservationParser6 > HostDataParser6
Parser for DHCPv4 host reservation.
HostDataParser< isc::dhcp::HostReservationParser4 > HostDataParser4
Parser for DHCPv4 host reservation.
void decodeFormattedHexString(const string &hex_string, vector< uint8_t > &binary)
Converts a formatted string of hexadecimal digits into a vector.
Definition str.cc:212
vector< uint8_t > quotedStringToBinary(const string &quoted_string)
Converts a string in quotes into vector.
Definition str.cc:139
Defines the logger used by the top-level component of kea-lfc.