Kea 3.3.3
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>
8
10#include <cc/data.h>
11#include <dhcp/dhcp6.h>
12#include <dhcp/option6_ia.h>
13#include <dhcp/option6_iaaddr.h>
15#include <dhcp/option_custom.h>
16#include <dhcp/pkt6.h>
18#include <dhcpsrv/cfgmgr.h>
19#include <dhcpsrv/lease.h>
21#include <eval/evaluate.h>
23#include <hooks/hooks.h>
24#include <util/str.h>
25
26#include <sstream>
27
29
30using namespace isc;
31using namespace isc::data;
32using namespace isc::dhcp;
33using namespace isc::util;
34using namespace isc::util::str;
35using namespace hooks;
36using namespace legal_log;
37using namespace std;
38
43std::string hwaddrSourceToString(uint32_t source) {
44 if (source == HWAddr::HWADDR_SOURCE_RAW) {
45 return ("Raw Socket");
46 }
47 if (source == HWAddr::HWADDR_SOURCE_DUID) {
48 return ("DUID");
49 }
51 return ("IPv6 Link Local");
52 }
54 return ("Client Address Relay Option");
55 }
56 if (source == HWAddr::HWADDR_SOURCE_REMOTE_ID) {
57 return ("Remote ID");
58 }
60 return ("Subscriber ID");
61 }
63 return ("DOCSIS CMTS");
64 }
66 return ("DOCSIS MODEM");
67 }
68
69 return ("UNKNOWN");
70}
71
75std::string genLease6Addr(const Lease6Ptr& lease) {
76 std::stringstream stream;
77
78 stream << lease->addr_;
79 if (lease->type_ == Lease::TYPE_PD) {
80 stream << "/" << static_cast<int>(lease->prefixlen_);
81 }
82
83 return (stream.str());
84}
85
86namespace isc {
87namespace dhcp {
88
91class TokenLeaseIA_NA : public virtual TokenOption {
92public:
98 TokenLeaseIA_NA(const Lease6Ptr& lease, const RepresentationType& rep_type)
99 : TokenOption({ D6O_IA_NA }, rep_type), lease_(lease) {
100 if (lease->type_ != Lease::TYPE_NA) {
101 isc_throw(EvalTypeError, "Can not create token using non IPv6 address type");
102 }
103 }
104
112 virtual OptionPtr getOption(Pkt& pkt) {
113 Pkt6* pkt6 = dynamic_cast<Pkt6*>(&pkt);
114 if (!pkt6) {
115 return (OptionPtr());
116 }
117 for (auto const& it : pkt6->getOptions(D6O_IA_NA)) {
118 auto const& ia = boost::dynamic_pointer_cast<Option6IA>(it.second);
119 if (ia && ia->getIAID() == lease_->iaid_) {
120 OptionCollection opts = ia->getOptions();
121 for (auto const& opt_it : opts) {
122 if (opt_it.second->getType() != D6O_IAADDR) {
123 continue;
124 }
125 Option6IAAddrPtr iaaddr =
126 boost::dynamic_pointer_cast<Option6IAAddr>(opt_it.second);
127 if (!iaaddr) {
128 continue;
129 }
130 if (iaaddr->getAddress() == lease_->addr_) {
131 boost::shared_ptr<Option6IA> ia_na(new Option6IA(D6O_IA_NA, ia->getIAID()));
132 ia_na->addOption(iaaddr);
133 for (auto const& other_opt_it : opts) {
134 if (other_opt_it.second->getType() == D6O_IAADDR ||
135 other_opt_it.second->getType() == D6O_IAPREFIX) {
136 continue;
137 }
138 ia_na->addOption(other_opt_it.second);
139 }
140 return (ia_na);
141 }
142 }
143 }
144 }
145 return (OptionPtr());
146 }
147
148private:
150 Lease6Ptr lease_;
151};
152
154class TokenFilterIA_NA : public virtual TokenOption {
155public:
159 TokenFilterIA_NA(const RepresentationType& rep_type) : TokenOption({ D6O_IA_NA }, rep_type) {
160 }
161
167 return (OptionPtr());
168 }
169};
170
174public:
181 : TokenOption({ D6O_IA_NA, D6O_IAADDR }, rep_type),
182 TokenLeaseIA_NA(lease, rep_type) {
183 }
184
192 virtual OptionPtr getOption(Pkt& pkt) {
194 if (option) {
195 option = option->getOption(D6O_IAADDR);
196 }
197 return (option);
198 }
199
206 unsigned evaluate(Pkt& pkt, ValueStack& values) {
207 return (TokenOption::evaluate(pkt, values));
208 }
209};
210
213public:
218 : TokenOption({ D6O_IA_NA, D6O_IAADDR }, rep_type),
219 TokenFilterIA_NA(rep_type) {
220 }
221
226 virtual OptionPtr getOption(Pkt& pkt) {
227 return (TokenFilterIA_NA::getOption(pkt));
228 }
229
236 unsigned evaluate(Pkt& pkt, ValueStack& values) {
237 return (TokenOption::evaluate(pkt, values));
238 }
239};
240
243class TokenLeaseIA_PD : public virtual TokenOption {
244public:
250 TokenLeaseIA_PD(const Lease6Ptr& lease, const RepresentationType& rep_type)
251 : TokenOption({ D6O_IA_PD }, rep_type), lease_(lease) {
252 if (lease->type_ != Lease::TYPE_PD) {
253 isc_throw(EvalTypeError, "Can not create token using non IPv6 prefix type");
254 }
255 }
256
264 virtual OptionPtr getOption(Pkt& pkt) {
265 Pkt6* pkt6 = dynamic_cast<Pkt6*>(&pkt);
266 if (!pkt6) {
267 return (OptionPtr());
268 }
269 for (auto const& it : pkt6->getOptions(D6O_IA_PD)) {
270 auto const& ia = boost::dynamic_pointer_cast<Option6IA>(it.second);
271 if (ia && ia->getIAID() == lease_->iaid_) {
272 OptionCollection opts = ia->getOptions();
273 for (auto const& opt_it : opts) {
274 if (opt_it.second->getType() != D6O_IAPREFIX) {
275 continue;
276 }
277 Option6IAPrefixPtr iaprefix =
278 boost::dynamic_pointer_cast<Option6IAPrefix>(opt_it.second);
279 if (!iaprefix) {
280 continue;
281 }
282 if ((iaprefix->getAddress() == lease_->addr_) &&
283 (iaprefix->getLength() == lease_->prefixlen_)) {
284 boost::shared_ptr<Option6IA> ia_pd(new Option6IA(D6O_IA_PD, ia->getIAID()));
285 ia_pd->addOption(iaprefix);
286 for (auto const& other_opt_it : opts) {
287 if (other_opt_it.second->getType() == D6O_IAADDR ||
288 other_opt_it.second->getType() == D6O_IAPREFIX) {
289 continue;
290 }
291 ia_pd->addOption(other_opt_it.second);
292 }
293 return (ia_pd);
294 }
295 }
296 }
297 }
298 return (OptionPtr());
299 }
300
301private:
303 Lease6Ptr lease_;
304};
305
307class TokenFilterIA_PD : public virtual TokenOption {
308public:
312 TokenFilterIA_PD(const RepresentationType& rep_type) : TokenOption({ D6O_IA_PD }, rep_type) {
313 }
314
320 return (OptionPtr());
321 }
322};
323
327public:
334 : TokenOption({ D6O_IA_PD, D6O_IAPREFIX }, rep_type),
335 TokenLeaseIA_PD(lease, rep_type) {
336 }
337
345 virtual OptionPtr getOption(Pkt& pkt) {
347 if (option) {
348 option = option->getOption(D6O_IAPREFIX);
349 }
350 return (option);
351 }
352
359 unsigned evaluate(Pkt& pkt, ValueStack& values) {
360 return (TokenOption::evaluate(pkt, values));
361 }
362};
363
366public:
371 : TokenOption({ D6O_IA_PD, D6O_IAPREFIX }, rep_type),
372 TokenFilterIA_PD(rep_type) {
373 }
374
379 virtual OptionPtr getOption(Pkt& pkt) {
380 return (TokenFilterIA_PD::getOption(pkt));
381 }
382
389 unsigned evaluate(Pkt& pkt, ValueStack& values) {
390 return (TokenOption::evaluate(pkt, values));
391 }
392};
393
394} // namespace dhcp
395} // namespace isc
396
404void filterLeaseIA_NA(isc::dhcp::Expression& expression, const Lease6Ptr& lease) {
405 for (size_t i = 0; i < expression.size(); ++i) {
406 boost::shared_ptr<TokenOption> option = boost::dynamic_pointer_cast<TokenOption>(expression[i]);
407 if (option) {
408 if (option->getOptions()[0] == D6O_IA_NA) {
409 if (option->getOptions().size() == 2U && option->getOptions()[1] == D6O_IAADDR) {
410 expression[i] = TokenPtr(new TokenLeaseIA_NASuboption(lease, option->getRepresentation()));
411 } else if (option->getOptions().size() == 1U) {
412 expression[i] = TokenPtr(new TokenLeaseIA_NA(lease, option->getRepresentation()));
413 }
414 continue;
415 }
416 if (option->getOptions()[0] == D6O_IA_PD) {
417 if (option->getOptions().size() == 2U && option->getOptions()[1] == D6O_IAPREFIX) {
418 expression[i] = TokenPtr(new TokenFilterIA_PDSuboption(option->getRepresentation()));
419 } else if (option->getOptions().size() == 1U) {
420 expression[i] = TokenPtr(new TokenFilterIA_PD(option->getRepresentation()));
421 }
422 continue;
423 }
424 }
425 }
426}
427
435void filterLeaseIA_PD(isc::dhcp::Expression& expression, const Lease6Ptr& lease) {
436 for (size_t i = 0; i < expression.size(); ++i) {
437 boost::shared_ptr<TokenOption> option = boost::dynamic_pointer_cast<TokenOption>(expression[i]);
438 if (option) {
439 if (option->getOptions()[0] == D6O_IA_NA) {
440 if (option->getOptions().size() == 2U && option->getOptions()[1] == D6O_IAADDR) {
441 expression[i] = TokenPtr(new TokenFilterIA_NASuboption(option->getRepresentation()));
442 } else if (option->getOptions().size() == 1U) {
443 expression[i] = TokenPtr(new TokenFilterIA_NA(option->getRepresentation()));
444 }
445 continue;
446 }
447 if (option->getOptions()[0] == D6O_IA_PD) {
448 if (option->getOptions().size() == 2U && option->getOptions()[1] == D6O_IAPREFIX) {
449 expression[i] = TokenPtr(new TokenLeaseIA_PDSuboption(lease, option->getRepresentation()));
450 } else if (option->getOptions().size() == 1U) {
451 expression[i] = TokenPtr(new TokenLeaseIA_PD(lease, option->getRepresentation()));
452 }
453 continue;
454 }
455 }
456 }
457}
458
468 const Lease6Ptr& lease) {
469 // Copy the expression so that is can be safely modified.
470 expression.reset(new isc::dhcp::Expression(*expression));
471 if (lease->type_ == Lease::TYPE_NA) {
472 filterLeaseIA_NA(*expression, lease);
473 } else if (lease->type_ == Lease::TYPE_PD) {
474 filterLeaseIA_PD(*expression, lease);
475 }
476}
477
485bool getCustomEntry(CalloutHandle& handle, const Pkt6Ptr& query, const Pkt6Ptr& response,
486 const Lease6Ptr& lease, std::string& value) {
487 bool using_custom_format = false;
488 auto library = LegalLogMgrFactory::instance(handle.getCurrentLibrary());
489 try {
490 auto expression = library->getRequestFormatExpression();
491 if (expression && query) {
492 replaceTokensForLease(expression, lease);
493
494 value = evaluateString(*expression, *query);
495 using_custom_format = true;
496 }
497
498 expression = library->getResponseFormatExpression();
499 if (expression && response) {
500 replaceTokensForLease(expression, lease);
501
502 value += evaluateString(*expression, *response);
503 using_custom_format = true;
504 }
505 } catch (const std::exception& ex) {
507 .arg(lease ? lease->addr_.toText() : "<none>")
508 .arg(lease && lease->duid_ ? lease->duid_->toText() : "<none>")
509 .arg(ex.what());
510 value.clear();
511 return (false);
512 }
513
514 return (using_custom_format);
515}
516
552/// @param lease DHCPv6 lease for which the entry should be created
553/// @param action Kind of event to log.
554std::string genLease6Entry(CalloutHandle& handle,
555 const Pkt6Ptr& query,
556 const Pkt6Ptr& response,
557 const Lease6Ptr& lease,
558 const Action& action) {
559 std::string value;
560 if (getCustomEntry(handle, query, response, lease, value)) {
561 return (value);
562 }
563
564 std::stringstream stream;
565
566 // <address>
567 if (lease->type_ != Lease::TYPE_PD) {
568 stream << "Address: " << lease->addr_;
569 } else {
570 stream << "Prefix: " << lease->addr_ << "/" << static_cast<int>(lease->prefixlen_);
571 }
572
573 stream << " has been " << actionToVerb(action);
574
575 if (action != Action::RELEASE) {
576 // <duration>
577 stream << " for " << LegalLogMgr::genDurationString(lease->valid_lft_) << " to";
578 } else {
579 stream << " from";
580 }
581
582 // <device-id>
583 stream << " a device with DUID: " << lease->duid_->toText();
584
585 if (lease->hwaddr_) {
586 stream << " and hardware address: " << lease->hwaddr_->toText()
587 << " (from " << hwaddrSourceToString(lease->hwaddr_->source_) << ")";
588 }
589
590 // Is it via relay(s)?
591 if (query->relay_info_.size()) {
592 const Pkt6::RelayInfo& server_relay = query->relay_info_[0];
593 stream << " connected via relay at address: " << server_relay.peeraddr_.toText()
594 << " for client on link address: " << server_relay.linkaddr_.toText()
595 << ", hop count: " << static_cast<int>(server_relay.hop_count_);
596
597 std::ostringstream idstream;
598 // Look for the remote-id option
599 OptionPtr opt = query->getAnyRelayOption(D6O_REMOTE_ID,
601 if (opt) {
602 const OptionBuffer id = opt->getData();
603 if (!id.empty()) {
604 idstream << "remote-id: " << dumpAsHex(id);
605
606 if (isPrintable(id)) {
607 idstream << " (" << LegalLogMgr::vectorDump(id) << ")";
608 }
609 }
610 }
611
612 // Look for the subscriber-id option
613 opt = query->getAnyRelayOption(D6O_SUBSCRIBER_ID,
615 if (opt) {
616 const OptionBuffer id = opt->getData();
617 if (!id.empty()) {
618 if (!idstream.str().empty()) {
619 idstream << " and ";
620 }
621
622 idstream << "subscriber-id: " << dumpAsHex(id);
623
624 if (isPrintable(id)) {
625 idstream << " (" << LegalLogMgr::vectorDump(id) << ")";
626 }
627 }
628 }
629
630 if (!idstream.str().empty()) {
631 stream << ", identified by " << idstream.str();
632 }
633
634 // Look for the interface-id option
635 std::ostringstream location;
636 opt = query->getAnyRelayOption(D6O_INTERFACE_ID,
638 if (opt) {
639 const OptionBuffer id = opt->getData();
640 if (!id.empty()) {
641 if (!idstream.str().empty()) {
642 idstream << " and ";
643 }
644
645 location << "interface-id: " << dumpAsHex(id);
646
647 if (isPrintable(id)) {
648 location << " (" << LegalLogMgr::vectorDump(id) << ")";
649 }
650 }
651 }
652
653 if (!location.str().empty()) {
654 stream << ", connected at location " << location.str();
655 }
656
657 }
658
659 ConstElementPtr ctx = lease->getContext();
660 if (ctx) {
661 stream << ", context: " << ctx->str();
662 }
663
664 return (stream.str());
665}
666
682///
683/// @return returns 0 upon success, non-zero otherwise
684int legalLog6Handler(CalloutHandle& handle, const Action& action) {
687 return (1);
688 }
689
690 // Fetch the client's packet and the lease callout arguments.
691 Pkt6Ptr query;
692 handle.getArgument("query6", query);
693
694 Pkt6Ptr response;
695 handle.getArgument("response6", response);
696
697 Lease6Ptr lease;
698 handle.getContext("lease6", lease);
699
700 if (!lease) {
701 return (0);
702 }
703
704 ConstCfgSubnets6Ptr cfg = CfgMgr::instance().getCurrentCfg()->getCfgSubnets6();
705 try {
706 ConstSubnet6Ptr subnet = cfg->getBySubnetId(lease->subnet_id_);
707
708 if (!isLoggingDisabled(subnet)) {
709 LegalLogMgrFactory::instance(handle.getCurrentLibrary())->writeln(genLease6Entry(handle, query, response,
710 lease, action),
711 genLease6Addr(lease));
712 }
713
714 } catch (const std::exception& ex) {
716 .arg(ex.what());
717 return (1);
718 }
719
720 return (0);
721}
722
723// Functions accessed by the hooks framework use C linkage to avoid the name
724// mangling that accompanies use of the C++ compiler as well as to avoid
725// issues related to namespaces.
726extern "C" {
727
733///
734/// @return 0 upon success, non-zero otherwise.
735int pkt6_receive(CalloutHandle& handle) {
736 handle.setContext("lease6", Lease4Ptr());
737 handle.setContext("leases6", Lease6CollectionPtr());
738 handle.setContext("deleted_leases6", Lease6CollectionPtr());
739 return (0);
740}
741
748///
749/// @return 0 upon success, non-zero otherwise.
750int leases6_committed(CalloutHandle& handle) {
752 if (status == CalloutHandle::NEXT_STEP_DROP ||
754 return (0);
755 }
756
757 Lease6CollectionPtr leases;
758 handle.getArgument("leases6", leases);
759 handle.setContext("leases6", leases);
760
761 Lease6CollectionPtr deleted_leases;
762 handle.getArgument("deleted_leases6", deleted_leases);
763 handle.setContext("deleted_leases6", deleted_leases);
764 return (0);
765}
766
773///
774/// @return 0 upon success, non-zero otherwise.
775int pkt6_send(CalloutHandle& handle) {
777 if (status == CalloutHandle::NEXT_STEP_DROP ||
779 return (0);
780 }
781
782 Lease6CollectionPtr leases;
783 handle.getContext("leases6", leases);
784
785 int current = 0;
786 int result = current;
787
788 if (leases) {
789 for (auto const& lease : *leases) {
790 handle.setContext("lease6", lease);
791 current = legalLog6Handler(handle, Action::ASSIGN);
792 if (current) {
793 result = current;
794 }
795 }
796 }
797
798 handle.getContext("deleted_leases6", leases);
799
800 if (leases) {
801 for (auto const& lease : *leases) {
802 handle.setContext("lease6", lease);
803 current = legalLog6Handler(handle, Action::RELEASE);
804 if (current) {
805 result = current;
806 }
807 }
808 }
809
810 return (result);
811}
812
819///
820/// @return 0 upon success, non-zero otherwise.
821int lease6_release(CalloutHandle& handle) {
823 if (status == CalloutHandle::NEXT_STEP_DROP ||
825 return (0);
826 }
827
828 Lease6Ptr lease;
829 handle.getArgument("lease6", lease);
830
832 handle.setContext("leases6", leases);
833
834 Lease6CollectionPtr deleted_leases(new Lease6Collection());
835 deleted_leases->push_back(lease);
836 handle.setContext("deleted_leases6", deleted_leases);
837
838 return (0);
839}
840
847///
848/// @return 0 upon success, non-zero otherwise.
849int lease6_decline(CalloutHandle& handle) {
851 if (status == CalloutHandle::NEXT_STEP_DROP ||
853 return (0);
854 }
855
856 Lease6Ptr lease;
857 handle.getArgument("lease6", lease);
858
860 handle.setContext("leases6", leases);
861
862 Lease6CollectionPtr deleted_leases(new Lease6Collection());
863 deleted_leases->push_back(lease);
864 handle.setContext("deleted_leases6", deleted_leases);
865
866 return (0);
867}
868
869} // 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:48
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:162
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:409
TokenOption(const std::vector< uint16_t > &option_codes, const RepresentationType &rep_type)
Constructor that takes an option code as a parameter.
Definition token.h:432
RepresentationType
Token representation type.
Definition token.h:419
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:23
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:530
std::vector< Lease6Ptr > Lease6Collection
A collection of IPv6 leases.
Definition lease.h:695
std::multimap< unsigned int, OptionPtr > OptionCollection
A collection of DHCP (v4 or v6) options.
Definition option.h:41
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:33
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:698
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:25
std::vector< TokenPtr > Expression
This is a structure that holds an expression converted to RPN.
Definition token.h:31
boost::shared_ptr< Lease4 > Lease4Ptr
Pointer to a Lease4 structure.
Definition lease.h:317
boost::shared_ptr< Option > OptionPtr
Definition option.h:38
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:36
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:51
@ TYPE_NA
the lease contains non-temporary IPv6 address
Definition lease.h:49
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