Kea 3.3.1
lease6_callouts.cc
Go to the documentation of this file.
1// Copyright (C) 2016-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>
9#include <cc/data.h>
10#include <dhcp/dhcp6.h>
11#include <dhcp/option_custom.h>
12#include <dhcp/option6_ia.h>
13#include <dhcp/option6_iaaddr.h>
15#include <dhcp/pkt6.h>
16#include <dhcpsrv/cfgmgr.h>
18#include <dhcpsrv/lease.h>
19#include <eval/evaluate.h>
20#include <hooks/hooks.h>
21#include <util/str.h>
22#include <legal_log_log.h>
25
26#include <sstream>
27
28using namespace isc;
29using namespace isc::data;
30using namespace isc::dhcp;
31using namespace isc::util;
32using namespace isc::util::str;
33using namespace hooks;
34using namespace legal_log;
35using namespace std;
36
41std::string hwaddrSourceToString(uint32_t source) {
42 if (source == HWAddr::HWADDR_SOURCE_RAW) {
43 return ("Raw Socket");
44 }
45 if (source == HWAddr::HWADDR_SOURCE_DUID) {
46 return ("DUID");
47 }
49 return ("IPv6 Link Local");
50 }
52 return ("Client Address Relay Option");
53 }
54 if (source == HWAddr::HWADDR_SOURCE_REMOTE_ID) {
55 return ("Remote ID");
56 }
58 return ("Subscriber ID");
59 }
61 return ("DOCSIS CMTS");
62 }
64 return ("DOCSIS MODEM");
65 }
66
67 return ("UNKNOWN");
68}
69
73std::string genLease6Addr(const Lease6Ptr& lease) {
74 std::stringstream stream;
75
76 stream << lease->addr_;
77 if (lease->type_ == Lease::TYPE_PD) {
78 stream << "/" << static_cast<int>(lease->prefixlen_);
79 }
80
81 return (stream.str());
82}
83
84namespace isc {
85namespace dhcp {
86
89class TokenLeaseIA_NA : public virtual TokenOption {
90public:
96 TokenLeaseIA_NA(const Lease6Ptr& lease, const RepresentationType& rep_type)
97 : TokenOption({ D6O_IA_NA }, rep_type), lease_(lease) {
98 if (lease->type_ != Lease::TYPE_NA) {
99 isc_throw(EvalTypeError, "Can not create token using non IPv6 address type");
100 }
101 }
102
110 virtual OptionPtr getOption(Pkt& pkt) {
111 Pkt6* pkt6 = dynamic_cast<Pkt6*>(&pkt);
112 if (!pkt6) {
113 return (OptionPtr());
114 }
115 for (auto const& it : pkt6->getOptions(D6O_IA_NA)) {
116 auto const& ia = boost::dynamic_pointer_cast<Option6IA>(it.second);
117 if (ia && ia->getIAID() == lease_->iaid_) {
118 OptionCollection opts = ia->getOptions();
119 for (auto const& opt_it : opts) {
120 if (opt_it.second->getType() != D6O_IAADDR) {
121 continue;
122 }
123 Option6IAAddrPtr iaaddr =
124 boost::dynamic_pointer_cast<Option6IAAddr>(opt_it.second);
125 if (!iaaddr) {
126 continue;
127 }
128 if (iaaddr->getAddress() == lease_->addr_) {
129 boost::shared_ptr<Option6IA> ia_na(new Option6IA(D6O_IA_NA, ia->getIAID()));
130 ia_na->addOption(iaaddr);
131 for (auto const& other_opt_it : opts) {
132 if (other_opt_it.second->getType() == D6O_IAADDR ||
133 other_opt_it.second->getType() == D6O_IAPREFIX) {
134 continue;
135 }
136 ia_na->addOption(other_opt_it.second);
137 }
138 return (ia_na);
139 }
140 }
141 }
142 }
143 return (OptionPtr());
144 }
145
146private:
148 Lease6Ptr lease_;
149};
150
152class TokenFilterIA_NA : public virtual TokenOption {
153public:
157 TokenFilterIA_NA(const RepresentationType& rep_type) : TokenOption({ D6O_IA_NA }, rep_type) {
158 }
159
165 return (OptionPtr());
166 }
167};
168
172public:
179 : TokenOption({ D6O_IA_NA, D6O_IAADDR }, rep_type),
180 TokenLeaseIA_NA(lease, rep_type) {
181 }
182
190 virtual OptionPtr getOption(Pkt& pkt) {
192 if (option) {
193 option = option->getOption(D6O_IAADDR);
194 }
195 return (option);
196 }
197
204 unsigned evaluate(Pkt& pkt, ValueStack& values) {
205 return (TokenOption::evaluate(pkt, values));
206 }
207};
208
211public:
216 : TokenOption({ D6O_IA_NA, D6O_IAADDR }, rep_type),
217 TokenFilterIA_NA(rep_type) {
218 }
219
224 virtual OptionPtr getOption(Pkt& pkt) {
225 return (TokenFilterIA_NA::getOption(pkt));
226 }
227
234 unsigned evaluate(Pkt& pkt, ValueStack& values) {
235 return (TokenOption::evaluate(pkt, values));
236 }
237};
238
241class TokenLeaseIA_PD : public virtual TokenOption {
242public:
248 TokenLeaseIA_PD(const Lease6Ptr& lease, const RepresentationType& rep_type)
249 : TokenOption({ D6O_IA_PD }, rep_type), lease_(lease) {
250 if (lease->type_ != Lease::TYPE_PD) {
251 isc_throw(EvalTypeError, "Can not create token using non IPv6 prefix type");
252 }
253 }
254
262 virtual OptionPtr getOption(Pkt& pkt) {
263 Pkt6* pkt6 = dynamic_cast<Pkt6*>(&pkt);
264 if (!pkt6) {
265 return (OptionPtr());
266 }
267 for (auto const& it : pkt6->getOptions(D6O_IA_PD)) {
268 auto const& ia = boost::dynamic_pointer_cast<Option6IA>(it.second);
269 if (ia && ia->getIAID() == lease_->iaid_) {
270 OptionCollection opts = ia->getOptions();
271 for (auto const& opt_it : opts) {
272 if (opt_it.second->getType() != D6O_IAPREFIX) {
273 continue;
274 }
275 Option6IAPrefixPtr iaprefix =
276 boost::dynamic_pointer_cast<Option6IAPrefix>(opt_it.second);
277 if (!iaprefix) {
278 continue;
279 }
280 if ((iaprefix->getAddress() == lease_->addr_) &&
281 (iaprefix->getLength() == lease_->prefixlen_)) {
282 boost::shared_ptr<Option6IA> ia_pd(new Option6IA(D6O_IA_PD, ia->getIAID()));
283 ia_pd->addOption(iaprefix);
284 for (auto const& other_opt_it : opts) {
285 if (other_opt_it.second->getType() == D6O_IAADDR ||
286 other_opt_it.second->getType() == D6O_IAPREFIX) {
287 continue;
288 }
289 ia_pd->addOption(other_opt_it.second);
290 }
291 return (ia_pd);
292 }
293 }
294 }
295 }
296 return (OptionPtr());
297 }
298
299private:
301 Lease6Ptr lease_;
302};
303
305class TokenFilterIA_PD : public virtual TokenOption {
306public:
310 TokenFilterIA_PD(const RepresentationType& rep_type) : TokenOption({ D6O_IA_PD }, rep_type) {
311 }
312
318 return (OptionPtr());
319 }
320};
321
325public:
332 : TokenOption({ D6O_IA_PD, D6O_IAPREFIX }, rep_type),
333 TokenLeaseIA_PD(lease, rep_type) {
334 }
335
343 virtual OptionPtr getOption(Pkt& pkt) {
345 if (option) {
346 option = option->getOption(D6O_IAPREFIX);
347 }
348 return (option);
349 }
350
357 unsigned evaluate(Pkt& pkt, ValueStack& values) {
358 return (TokenOption::evaluate(pkt, values));
359 }
360};
361
364public:
369 : TokenOption({ D6O_IA_PD, D6O_IAPREFIX }, rep_type),
370 TokenFilterIA_PD(rep_type) {
371 }
372
377 virtual OptionPtr getOption(Pkt& pkt) {
378 return (TokenFilterIA_PD::getOption(pkt));
379 }
380
387 unsigned evaluate(Pkt& pkt, ValueStack& values) {
388 return (TokenOption::evaluate(pkt, values));
389 }
390};
391
392} // namespace dhcp
393} // namespace isc
394
402void filterLeaseIA_NA(isc::dhcp::Expression& expression, const Lease6Ptr& lease) {
403 for (size_t i = 0; i < expression.size(); ++i) {
404 boost::shared_ptr<TokenOption> option = boost::dynamic_pointer_cast<TokenOption>(expression[i]);
405 if (option) {
406 if (option->getOptions()[0] == D6O_IA_NA) {
407 if (option->getOptions().size() == 2U && option->getOptions()[1] == D6O_IAADDR) {
408 expression[i] = TokenPtr(new TokenLeaseIA_NASuboption(lease, option->getRepresentation()));
409 } else if (option->getOptions().size() == 1U) {
410 expression[i] = TokenPtr(new TokenLeaseIA_NA(lease, option->getRepresentation()));
411 }
412 continue;
413 }
414 if (option->getOptions()[0] == D6O_IA_PD) {
415 if (option->getOptions().size() == 2U && option->getOptions()[1] == D6O_IAPREFIX) {
416 expression[i] = TokenPtr(new TokenFilterIA_PDSuboption(option->getRepresentation()));
417 } else if (option->getOptions().size() == 1U) {
418 expression[i] = TokenPtr(new TokenFilterIA_PD(option->getRepresentation()));
419 }
420 continue;
421 }
422 }
423 }
424}
425
433void filterLeaseIA_PD(isc::dhcp::Expression& expression, const Lease6Ptr& lease) {
434 for (size_t i = 0; i < expression.size(); ++i) {
435 boost::shared_ptr<TokenOption> option = boost::dynamic_pointer_cast<TokenOption>(expression[i]);
436 if (option) {
437 if (option->getOptions()[0] == D6O_IA_NA) {
438 if (option->getOptions().size() == 2U && option->getOptions()[1] == D6O_IAADDR) {
439 expression[i] = TokenPtr(new TokenFilterIA_NASuboption(option->getRepresentation()));
440 } else if (option->getOptions().size() == 1U) {
441 expression[i] = TokenPtr(new TokenFilterIA_NA(option->getRepresentation()));
442 }
443 continue;
444 }
445 if (option->getOptions()[0] == D6O_IA_PD) {
446 if (option->getOptions().size() == 2U && option->getOptions()[1] == D6O_IAPREFIX) {
447 expression[i] = TokenPtr(new TokenLeaseIA_PDSuboption(lease, option->getRepresentation()));
448 } else if (option->getOptions().size() == 1U) {
449 expression[i] = TokenPtr(new TokenLeaseIA_PD(lease, option->getRepresentation()));
450 }
451 continue;
452 }
453 }
454 }
455}
456
466 const Lease6Ptr& lease) {
467 // Copy the expression so that is can be safely modified.
468 expression.reset(new isc::dhcp::Expression(*expression));
469 if (lease->type_ == Lease::TYPE_NA) {
470 filterLeaseIA_NA(*expression, lease);
471 } else if (lease->type_ == Lease::TYPE_PD) {
472 filterLeaseIA_PD(*expression, lease);
473 }
474}
475
483bool getCustomEntry(CalloutHandle& handle, const Pkt6Ptr& query, const Pkt6Ptr& response,
484 const Lease6Ptr& lease, std::string& value) {
485 bool using_custom_format = false;
486 auto library = LegalLogMgrFactory::instance(handle.getCurrentLibrary());
487 try {
488 auto expression = library->getRequestFormatExpression();
489 if (expression && query) {
490 replaceTokensForLease(expression, lease);
491
492 value = evaluateString(*expression, *query);
493 using_custom_format = true;
494 }
495
496 expression = library->getResponseFormatExpression();
497 if (expression && response) {
498 replaceTokensForLease(expression, lease);
499
500 value += evaluateString(*expression, *response);
501 using_custom_format = true;
502 }
503 } catch (const std::exception& ex) {
505 .arg(lease ? lease->addr_.toText() : "<none>")
506 .arg(lease && lease->duid_ ? lease->duid_->toText() : "<none>")
507 .arg(ex.what());
508 value.clear();
509 return (false);
510 }
511
512 return (using_custom_format);
513}
514
550/// @param lease DHCPv6 lease for which the entry should be created
551/// @param action Kind of event to log.
552std::string genLease6Entry(CalloutHandle& handle,
553 const Pkt6Ptr& query,
554 const Pkt6Ptr& response,
555 const Lease6Ptr& lease,
556 const Action& action) {
557 std::string value;
558 if (getCustomEntry(handle, query, response, lease, value)) {
559 return (value);
560 }
561
562 std::stringstream stream;
563
564 // <address>
565 if (lease->type_ != Lease::TYPE_PD) {
566 stream << "Address: " << lease->addr_;
567 } else {
568 stream << "Prefix: " << lease->addr_ << "/" << static_cast<int>(lease->prefixlen_);
569 }
570
571 stream << " has been " << actionToVerb(action);
572
573 if (action != Action::RELEASE) {
574 // <duration>
575 stream << " for " << LegalLogMgr::genDurationString(lease->valid_lft_) << " to";
576 } else {
577 stream << " from";
578 }
579
580 // <device-id>
581 stream << " a device with DUID: " << lease->duid_->toText();
582
583 if (lease->hwaddr_) {
584 stream << " and hardware address: " << lease->hwaddr_->toText()
585 << " (from " << hwaddrSourceToString(lease->hwaddr_->source_) << ")";
586 }
587
588 // Is it via relay(s)?
589 if (query->relay_info_.size()) {
590 const Pkt6::RelayInfo& server_relay = query->relay_info_[0];
591 stream << " connected via relay at address: " << server_relay.peeraddr_.toText()
592 << " for client on link address: " << server_relay.linkaddr_.toText()
593 << ", hop count: " << static_cast<int>(server_relay.hop_count_);
594
595 std::ostringstream idstream;
596 // Look for the remote-id option
597 OptionPtr opt = query->getAnyRelayOption(D6O_REMOTE_ID,
599 if (opt) {
600 const OptionBuffer id = opt->getData();
601 if (!id.empty()) {
602 idstream << "remote-id: " << dumpAsHex(id);
603
604 if (isPrintable(id)) {
605 idstream << " (" << LegalLogMgr::vectorDump(id) << ")";
606 }
607 }
608 }
609
610 // Look for the subscriber-id option
611 opt = query->getAnyRelayOption(D6O_SUBSCRIBER_ID,
613 if (opt) {
614 const OptionBuffer id = opt->getData();
615 if (!id.empty()) {
616 if (!idstream.str().empty()) {
617 idstream << " and ";
618 }
619
620 idstream << "subscriber-id: " << dumpAsHex(id);
621
622 if (isPrintable(id)) {
623 idstream << " (" << LegalLogMgr::vectorDump(id) << ")";
624 }
625 }
626 }
627
628 if (!idstream.str().empty()) {
629 stream << ", identified by " << idstream.str();
630 }
631
632 // Look for the interface-id option
633 std::ostringstream location;
634 opt = query->getAnyRelayOption(D6O_INTERFACE_ID,
636 if (opt) {
637 const OptionBuffer id = opt->getData();
638 if (!id.empty()) {
639 if (!idstream.str().empty()) {
640 idstream << " and ";
641 }
642
643 location << "interface-id: " << dumpAsHex(id);
644
645 if (isPrintable(id)) {
646 location << " (" << LegalLogMgr::vectorDump(id) << ")";
647 }
648 }
649 }
650
651 if (!location.str().empty()) {
652 stream << ", connected at location " << location.str();
653 }
654
655 }
656
657 ConstElementPtr ctx = lease->getContext();
658 if (ctx) {
659 stream << ", context: " << ctx->str();
660 }
661
662 return (stream.str());
663}
664
680///
681/// @return returns 0 upon success, non-zero otherwise
682int legalLog6Handler(CalloutHandle& handle, const Action& action) {
685 return (1);
686 }
687
688 // Fetch the client's packet and the lease callout arguments.
689 Pkt6Ptr query;
690 handle.getArgument("query6", query);
691
692 Pkt6Ptr response;
693 handle.getArgument("response6", response);
694
695 Lease6Ptr lease;
696 handle.getContext("lease6", lease);
697
698 if (!lease) {
699 return (0);
700 }
701
702 ConstCfgSubnets6Ptr cfg = CfgMgr::instance().getCurrentCfg()->getCfgSubnets6();
703 try {
704 ConstSubnet6Ptr subnet = cfg->getBySubnetId(lease->subnet_id_);
705
706 if (!isLoggingDisabled(subnet)) {
707 LegalLogMgrFactory::instance(handle.getCurrentLibrary())->writeln(genLease6Entry(handle, query, response,
708 lease, action),
709 genLease6Addr(lease));
710 }
711
712 } catch (const std::exception& ex) {
714 .arg(ex.what());
715 return (1);
716 }
717
718 return (0);
719}
720
721// Functions accessed by the hooks framework use C linkage to avoid the name
722// mangling that accompanies use of the C++ compiler as well as to avoid
723// issues related to namespaces.
724extern "C" {
725
731///
732/// @return 0 upon success, non-zero otherwise.
733int pkt6_receive(CalloutHandle& handle) {
734 handle.setContext("lease6", Lease4Ptr());
735 handle.setContext("leases6", Lease6CollectionPtr());
736 handle.setContext("deleted_leases6", Lease6CollectionPtr());
737 return (0);
738}
739
746///
747/// @return 0 upon success, non-zero otherwise.
748int leases6_committed(CalloutHandle& handle) {
750 if (status == CalloutHandle::NEXT_STEP_DROP ||
752 return (0);
753 }
754
755 Lease6CollectionPtr leases;
756 handle.getArgument("leases6", leases);
757 handle.setContext("leases6", leases);
758
759 Lease6CollectionPtr deleted_leases;
760 handle.getArgument("deleted_leases6", deleted_leases);
761 handle.setContext("deleted_leases6", deleted_leases);
762 return (0);
763}
764
771///
772/// @return 0 upon success, non-zero otherwise.
773int pkt6_send(CalloutHandle& handle) {
775 if (status == CalloutHandle::NEXT_STEP_DROP ||
777 return (0);
778 }
779
780 Lease6CollectionPtr leases;
781 handle.getContext("leases6", leases);
782
783 int current = 0;
784 int result = current;
785
786 if (leases) {
787 for (auto const& lease : *leases) {
788 handle.setContext("lease6", lease);
789 current = legalLog6Handler(handle, Action::ASSIGN);
790 if (current) {
791 result = current;
792 }
793 }
794 }
795
796 handle.getContext("deleted_leases6", leases);
797
798 if (leases) {
799 for (auto const& lease : *leases) {
800 handle.setContext("lease6", lease);
801 current = legalLog6Handler(handle, Action::RELEASE);
802 if (current) {
803 result = current;
804 }
805 }
806 }
807
808 return (result);
809}
810
817///
818/// @return 0 upon success, non-zero otherwise.
819int lease6_release(CalloutHandle& handle) {
821 if (status == CalloutHandle::NEXT_STEP_DROP ||
823 return (0);
824 }
825
826 Lease6Ptr lease;
827 handle.getArgument("lease6", lease);
828
830 handle.setContext("leases6", leases);
831
832 Lease6CollectionPtr deleted_leases(new Lease6Collection());
833 deleted_leases->push_back(lease);
834 handle.setContext("deleted_leases6", deleted_leases);
835
836 return (0);
837}
838
845///
846/// @return 0 upon success, non-zero otherwise.
847int lease6_decline(CalloutHandle& handle) {
849 if (status == CalloutHandle::NEXT_STEP_DROP ||
851 return (0);
852 }
853
854 Lease6Ptr lease;
855 handle.getArgument("lease6", lease);
856
858 handle.setContext("leases6", leases);
859
860 Lease6CollectionPtr deleted_leases(new Lease6Collection());
861 deleted_leases->push_back(lease);
862 handle.setContext("deleted_leases6", deleted_leases);
863
864 return (0);
865}
866
867} // end extern "C"
CalloutNextStep
Specifies allowed next steps.
@ NEXT_STEP_DROP
drop the packet
@ NEXT_STEP_SKIP
skip the next processing step
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
EvalTypeError is thrown when a value on the stack has a content with an unexpected type.
Definition token.h:46
static LegalLogMgrPtr & instance(ManagerID id=0)
Returns the forensic backend manager with specified ID.
static std::string genDurationString(const uint32_t secs)
Translates seconds into a text string of days, hours, minutes and seconds.
static std::string vectorDump(const std::vector< uint8_t > &bytes)
Creates a string from a vector of printable bytes.
Represents a DHCPv6 packet.
Definition pkt6.h:44
@ RELAY_SEARCH_FROM_CLIENT
Definition pkt6.h:75
Base class for classes representing DHCP messages.
Definition pkt.h:161
isc::dhcp::OptionCollection getOptions(const uint16_t type)
Returns all instances of specified type.
Definition pkt.cc:91
Filter all IA_NA so that no sub-option is matched by the expression.
unsigned evaluate(Pkt &pkt, ValueStack &values)
Evaluate the expression using the TokenOption implementation.
TokenFilterIA_NASuboption(const RepresentationType &rep_type)
Constructor.
virtual OptionPtr getOption(Pkt &pkt)
Get no option regardless of what the packet contains.
Filter all IA_NA so that no option is matched by the expression.
virtual OptionPtr getOption(Pkt &)
Get no option regardless of what the packet contains.
TokenFilterIA_NA(const RepresentationType &rep_type)
Constructor.
Filter all IA_PD so that no sub-option is matched by the expression.
TokenFilterIA_PDSuboption(const RepresentationType &rep_type)
Constructor.
virtual OptionPtr getOption(Pkt &pkt)
Get no option regardless of what the packet contains.
unsigned evaluate(Pkt &pkt, ValueStack &values)
Evaluate the expression using the TokenOption implementation.
Filter all IA_PD so that no option is matched by the expression.
virtual OptionPtr getOption(Pkt &)
Get no option regardless of what the packet contains.
TokenFilterIA_PD(const RepresentationType &rep_type)
Constructor.
Filter the IA_NA (3) option containing the OPTION_IAADDR (5) option matching the respective lease.
unsigned evaluate(Pkt &pkt, ValueStack &values)
Evaluate the expression using the TokenOption implementation.
TokenLeaseIA_NASuboption(const Lease6Ptr &lease, const RepresentationType &rep_type)
Constructor.
virtual OptionPtr getOption(Pkt &pkt)
Get the IA_NA (3) option containing the OPTION_IAADDR (5) option matching the respective lease.
Filter the IA_NA (3) option containing the OPTION_IAADDR (5) option matching the respective lease.
virtual OptionPtr getOption(Pkt &pkt)
Get the IA_NA (3) option containing the OPTION_IAADDR (5) option matching the respective lease.
TokenLeaseIA_NA(const Lease6Ptr &lease, const RepresentationType &rep_type)
Constructor.
Filter the IA_PD (25) option containing the OPTION_IAPREFIX (25) option matching the respective lease...
TokenLeaseIA_PDSuboption(const Lease6Ptr &lease, const RepresentationType &rep_type)
Constructor.
unsigned evaluate(Pkt &pkt, ValueStack &values)
Evaluate the expression using the TokenOption implementation.
virtual OptionPtr getOption(Pkt &pkt)
Get the IA_PD (25) option containing the OPTION_IAPREFIX (25) option matching the respective lease.
Filter the IA_PD (25) option containing the OPTION_IAPREFIX (25) option matching the respective lease...
virtual OptionPtr getOption(Pkt &pkt)
Get the IA_PD (25) option containing the OPTION_IAPREFIX (25) option matching the respective lease.
TokenLeaseIA_PD(const Lease6Ptr &lease, const RepresentationType &rep_type)
Constructor.
Token that represents a value of an option.
Definition token.h:407
RepresentationType
Token representation type.
Definition token.h:417
TokenOption(const std::vector< uint16_t > &option_codes, const RepresentationType &rep_type)
Constructor that takes an option code as a parameter.
Definition token.h:430
virtual unsigned evaluate(Pkt &pkt, ValueStack &values)
Evaluates the values of the option.
Definition token.cc:418
Per-packet callout handle.
void getContext(const std::string &name, T &value) const
Get context.
void setContext(const std::string &name, T value)
Set context.
CalloutNextStep getStatus() const
Returns the next processing step.
void getArgument(const std::string &name, T &value) const
Get argument.
int getCurrentLibrary() const
Get current library index.
@ D6O_INTERFACE_ID
Definition dhcp6.h:38
@ D6O_REMOTE_ID
Definition dhcp6.h:57
@ D6O_SUBSCRIBER_ID
Definition dhcp6.h:58
@ D6O_IA_NA
Definition dhcp6.h:23
@ D6O_IA_PD
Definition dhcp6.h:45
@ D6O_IAADDR
Definition dhcp6.h:25
@ D6O_IAPREFIX
Definition dhcp6.h:46
#define isc_throw(type, stream)
A shortcut macro to insert known values into exception arguments.
static const uint32_t HWADDR_SOURCE_RAW
Obtained first hand from raw socket (100% reliable).
Definition hwaddr.h:44
static const uint32_t HWADDR_SOURCE_REMOTE_ID
A relay can insert remote-id.
Definition hwaddr.h:63
static const uint32_t HWADDR_SOURCE_CLIENT_ADDR_RELAY_OPTION
Get it from RFC6939 option.
Definition hwaddr.h:59
static const uint32_t HWADDR_SOURCE_IPV6_LINK_LOCAL
Extracted from IPv6 link-local address.
Definition hwaddr.h:53
static const uint32_t HWADDR_SOURCE_DOCSIS_MODEM
A cable modem (acting as DHCP client) that supports DOCSIS standard can insert DOCSIS options that co...
Definition hwaddr.h:79
static const uint32_t HWADDR_SOURCE_DUID
Extracted from DUID-LL or DUID-LLT (not 100% reliable as the client can send fake DUID).
Definition hwaddr.h:48
static const uint32_t HWADDR_SOURCE_DOCSIS_CMTS
A CMTS (acting as DHCP relay agent) that supports DOCSIS standard can insert DOCSIS options that cont...
Definition hwaddr.h:73
static const uint32_t HWADDR_SOURCE_SUBSCRIBER_ID
A relay can insert a subscriber-id option.
Definition hwaddr.h:67
void replaceTokensForLease(isc::dhcp::ExpressionPtr &expression, const Lease6Ptr &lease)
Replace TokenOption expression tokens for all IA_NA and IA_PD options and sub-options filtering by th...
int leases6_committed(CalloutHandle &handle)
This callout is called at the "leases6_committed" hook.
void filterLeaseIA_NA(isc::dhcp::Expression &expression, const Lease6Ptr &lease)
Replace TokenOption expression tokens with the IA_NA (3) option containing the OPTION_IAADDR (5) opti...
std::string genLease6Entry(CalloutHandle &handle, const Pkt6Ptr &query, const Pkt6Ptr &response, const Lease6Ptr &lease, const Action &action)
Creates legal store entry for a DHCPv6 Lease.
int lease6_release(CalloutHandle &handle)
This callout is called at the "lease6_release" hook.
void filterLeaseIA_PD(isc::dhcp::Expression &expression, const Lease6Ptr &lease)
Replace TokenOption expression tokens with the IA_PD (25) option containing the OPTION_IAPREFIX (25) ...
std::string genLease6Addr(const Lease6Ptr &lease)
Creates legal store address column for a DHCPv6 Lease.
int pkt6_send(CalloutHandle &handle)
This callout is called at the "pkt6_send" hook.
std::string hwaddrSourceToString(uint32_t source)
Function which converts hardware address source to a string.
int pkt6_receive(CalloutHandle &handle)
This callout is called at the "pkt6_receive" hook.
bool getCustomEntry(CalloutHandle &handle, const Pkt6Ptr &query, const Pkt6Ptr &response, const Lease6Ptr &lease, std::string &value)
Create custom log entry for the current lease.
int legalLog6Handler(CalloutHandle &handle, const Action &action)
Produces an DHCPv6 legal log entry from a callout handle.
int lease6_decline(CalloutHandle &handle)
This callout is called at the "lease6_decline" hook.
const isc::log::MessageID LEGAL_LOG_LEASE6_NO_LEGAL_STORE
const isc::log::MessageID LEGAL_LOG_LEASE6_RENDER_ERROR
const isc::log::MessageID LEGAL_LOG_LEASE6_WRITE_ERROR
#define LOG_ERROR(LOGGER, MESSAGE)
Macro to conveniently test error output and log it.
Definition macros.h:32
boost::shared_ptr< const Element > ConstElementPtr
Definition data.h:30
boost::shared_ptr< Token > TokenPtr
Pointer to a single Token.
Definition token.h:21
boost::shared_ptr< const Subnet6 > ConstSubnet6Ptr
A const pointer to a Subnet6 object.
Definition subnet.h:620
boost::shared_ptr< Lease6 > Lease6Ptr
Pointer to a Lease6 structure.
Definition lease.h:528
std::vector< Lease6Ptr > Lease6Collection
A collection of IPv6 leases.
Definition lease.h:693
std::multimap< unsigned int, OptionPtr > OptionCollection
A collection of DHCP (v4 or v6) options.
Definition option.h:40
std::string evaluateString(const Expression &expr, Pkt &pkt)
Evaluate a RPN expression for a v4 or v6 packet and return a string value.
Definition evaluate.cc:45
boost::shared_ptr< Option6IAPrefix > Option6IAPrefixPtr
Pointer to the Option6IAPrefix object.
const string actionToVerb(Action action)
Translates an Action into its corresponding verb.
boost::shared_ptr< Expression > ExpressionPtr
Definition token.h:31
boost::shared_ptr< Option6IAAddr > Option6IAAddrPtr
A pointer to the isc::dhcp::Option6IAAddr object.
boost::shared_ptr< const CfgSubnets6 > ConstCfgSubnets6Ptr
Const pointer.
boost::shared_ptr< Lease6Collection > Lease6CollectionPtr
A shared pointer to the collection of IPv6 leases.
Definition lease.h:696
boost::shared_ptr< Pkt6 > Pkt6Ptr
A pointer to Pkt6 packet.
Definition pkt6.h:31
std::vector< uint8_t > OptionBuffer
buffer types used in DHCP code.
Definition option.h:24
std::vector< TokenPtr > Expression
This is a structure that holds an expression converted to RPN.
Definition token.h:29
boost::shared_ptr< Lease4 > Lease4Ptr
Pointer to a Lease4 structure.
Definition lease.h:315
boost::shared_ptr< Option > OptionPtr
Definition option.h:37
Action
Describe what kind of event is being logged.
std::stack< std::string > ValueStack
Evaluated values are stored as a stack of strings.
Definition token.h:34
isc::log::Logger legal_log_logger("legal-log-hooks")
Legal Log Logger.
bool isLoggingDisabled(const SubnetPtrType &subnet)
Checks if legal logging is disabled for a subnet.
string dumpAsHex(const uint8_t *data, size_t length)
Dumps a buffer of bytes as a string of hexadecimal digits.
Definition str.cc:330
bool isPrintable(const string &content)
Check if a string is printable.
Definition str.cc:310
Defines the logger used by the top-level component of kea-lfc.
@ TYPE_PD
the lease contains IPv6 prefix (for prefix delegation)
Definition lease.h:49
@ TYPE_NA
the lease contains non-temporary IPv6 address
Definition lease.h:47
structure that describes a single relay information
Definition pkt6.h:85
isc::asiolink::IOAddress linkaddr_
fixed field in relay-forw/relay-reply
Definition pkt6.h:96
uint8_t hop_count_
number of traversed relays (up to 32)
Definition pkt6.h:95
isc::asiolink::IOAddress peeraddr_
fixed field in relay-forw/relay-reply
Definition pkt6.h:97