Kea 3.1.1
lease6_callouts.cc
Go to the documentation of this file.
1// Copyright (C) 2016-2025 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 hooks;
33using namespace legal_log;
34using namespace std;
35
40std::string hwaddrSourceToString(uint32_t source) {
41 if (source == HWAddr::HWADDR_SOURCE_RAW) {
42 return ("Raw Socket");
43 }
44 if (source == HWAddr::HWADDR_SOURCE_DUID) {
45 return ("DUID");
46 }
48 return ("IPv6 Link Local");
49 }
51 return ("Client Address Relay Option");
52 }
53 if (source == HWAddr::HWADDR_SOURCE_REMOTE_ID) {
54 return ("Remote ID");
55 }
57 return ("Subscriber ID");
58 }
60 return ("DOCSIS CMTS");
61 }
63 return ("DOCSIS MODEM");
64 }
65
66 return ("UNKNOWN");
67}
68
72std::string genLease6Addr(const Lease6Ptr& lease) {
73 std::stringstream stream;
74
75 stream << lease->addr_;
76 if (lease->type_ == Lease::TYPE_PD) {
77 stream << "/" << static_cast<int>(lease->prefixlen_);
78 }
79
80 return (stream.str());
81}
82
83namespace isc {
84namespace dhcp {
85
88class TokenLeaseIA_NA : public virtual TokenOption {
89public:
95 TokenLeaseIA_NA(const Lease6Ptr& lease, const RepresentationType& rep_type)
96 : TokenOption(D6O_IA_NA, rep_type), lease_(lease) {
97 if (lease->type_ != Lease::TYPE_NA) {
98 isc_throw(EvalTypeError, "Can not create token using non IPv6 address type");
99 }
100 }
101
109 virtual OptionPtr getOption(Pkt& pkt) {
110 Pkt6* pkt6 = dynamic_cast<Pkt6*>(&pkt);
111 if (!pkt6) {
112 return (OptionPtr());
113 }
114 for (auto const& it : pkt6->getOptions(D6O_IA_NA)) {
115 auto const& ia = boost::dynamic_pointer_cast<Option6IA>(it.second);
116 if (ia && ia->getIAID() == lease_->iaid_) {
117 OptionCollection opts = ia->getOptions();
118 for (auto const& opt_it : opts) {
119 if (opt_it.second->getType() != D6O_IAADDR) {
120 continue;
121 }
122 Option6IAAddrPtr iaaddr =
123 boost::dynamic_pointer_cast<Option6IAAddr>(opt_it.second);
124 if (!iaaddr) {
125 continue;
126 }
127 if (iaaddr->getAddress() == lease_->addr_) {
128 boost::shared_ptr<Option6IA> ia_na(new Option6IA(D6O_IA_NA, ia->getIAID()));
129 ia_na->addOption(iaaddr);
130 for (auto const& other_opt_it : opts) {
131 if (other_opt_it.second->getType() == D6O_IAADDR ||
132 other_opt_it.second->getType() == D6O_IAPREFIX) {
133 continue;
134 }
135 ia_na->addOption(other_opt_it.second);
136 }
137 return (ia_na);
138 }
139 }
140 }
141 }
142 return (OptionPtr());
143 }
144
145private:
147 Lease6Ptr lease_;
148};
149
151class TokenFilterIA_NA : public virtual TokenOption {
152public:
157 }
158
164 return (OptionPtr());
165 }
166};
167
170class TokenLeaseIA_NASuboption : public virtual TokenLeaseIA_NA, public virtual TokenSubOption {
171public:
178 : TokenOption(D6O_IA_NA, rep_type), TokenLeaseIA_NA(lease, rep_type),
180 }
181
189 virtual OptionPtr getOption(Pkt& pkt) {
190 return (TokenLeaseIA_NA::getOption(pkt));
191 }
192
199 unsigned evaluate(Pkt& pkt, ValueStack& values) {
200 return (TokenSubOption::evaluate(pkt, values));
201 }
202};
203
205class TokenFilterIA_NASuboption : public virtual TokenFilterIA_NA, public virtual TokenSubOption {
206public:
211 : TokenOption(D6O_IA_NA, rep_type), TokenFilterIA_NA(rep_type),
213 }
214
219 virtual OptionPtr getOption(Pkt& pkt) {
220 return (TokenFilterIA_NA::getOption(pkt));
221 }
222
229 unsigned evaluate(Pkt& pkt, ValueStack& values) {
230 return (TokenSubOption::evaluate(pkt, values));
231 }
232};
233
236class TokenLeaseIA_PD : public virtual TokenOption {
237public:
243 TokenLeaseIA_PD(const Lease6Ptr& lease, const RepresentationType& rep_type)
244 : TokenOption(D6O_IA_PD, rep_type), lease_(lease) {
245 if (lease->type_ != Lease::TYPE_PD) {
246 isc_throw(EvalTypeError, "Can not create token using non IPv6 prefix type");
247 }
248 }
249
257 virtual OptionPtr getOption(Pkt& pkt) {
258 Pkt6* pkt6 = dynamic_cast<Pkt6*>(&pkt);
259 if (!pkt6) {
260 return (OptionPtr());
261 }
262 for (auto const& it : pkt6->getOptions(D6O_IA_PD)) {
263 auto const& ia = boost::dynamic_pointer_cast<Option6IA>(it.second);
264 if (ia && ia->getIAID() == lease_->iaid_) {
265 OptionCollection opts = ia->getOptions();
266 for (auto const& opt_it : opts) {
267 if (opt_it.second->getType() != D6O_IAPREFIX) {
268 continue;
269 }
270 Option6IAPrefixPtr iaprefix =
271 boost::dynamic_pointer_cast<Option6IAPrefix>(opt_it.second);
272 if (!iaprefix) {
273 continue;
274 }
275 if ((iaprefix->getAddress() == lease_->addr_) &&
276 (iaprefix->getLength() == lease_->prefixlen_)) {
277 boost::shared_ptr<Option6IA> ia_pd(new Option6IA(D6O_IA_PD, ia->getIAID()));
278 ia_pd->addOption(iaprefix);
279 for (auto const& other_opt_it : opts) {
280 if (other_opt_it.second->getType() == D6O_IAADDR ||
281 other_opt_it.second->getType() == D6O_IAPREFIX) {
282 continue;
283 }
284 ia_pd->addOption(other_opt_it.second);
285 }
286 return (ia_pd);
287 }
288 }
289 }
290 }
291 return (OptionPtr());
292 }
293
294private:
296 Lease6Ptr lease_;
297};
298
300class TokenFilterIA_PD : public virtual TokenOption {
301public:
306 }
307
313 return (OptionPtr());
314 }
315};
316
319class TokenLeaseIA_PDSuboption : public virtual TokenLeaseIA_PD, public virtual TokenSubOption {
320public:
327 : TokenOption(D6O_IA_PD, rep_type), TokenLeaseIA_PD(lease, rep_type),
329 }
330
338 virtual OptionPtr getOption(Pkt& pkt) {
339 return (TokenLeaseIA_PD::getOption(pkt));
340 }
341
348 unsigned evaluate(Pkt& pkt, ValueStack& values) {
349 return (TokenSubOption::evaluate(pkt, values));
350 }
351};
352
354class TokenFilterIA_PDSuboption : public virtual TokenFilterIA_PD, public virtual TokenSubOption {
355public:
360 : TokenOption(D6O_IA_PD, rep_type), TokenFilterIA_PD(rep_type),
362 }
363
368 virtual OptionPtr getOption(Pkt& pkt) {
369 return (TokenFilterIA_PD::getOption(pkt));
370 }
371
378 unsigned evaluate(Pkt& pkt, ValueStack& values) {
379 return (TokenSubOption::evaluate(pkt, values));
380 }
381};
382
383} // namespace dhcp
384} // namespace isc
385
394void filterLeaseIA_NA(isc::dhcp::Expression& expression, const Lease6Ptr& lease) {
395 for (size_t i = 0; i < expression.size(); ++i) {
396 boost::shared_ptr<TokenSubOption> suboption = boost::dynamic_pointer_cast<TokenSubOption>(expression[i]);
397 if (suboption) {
398 if ((suboption->getCode() == D6O_IA_NA) && (suboption->getSubCode() == D6O_IAADDR)) {
399 expression[i] = TokenPtr(new TokenLeaseIA_NASuboption(lease, suboption->getRepresentation()));
400 continue;
401 }
402 if ((suboption->getCode() == D6O_IA_PD) && (suboption->getSubCode() == D6O_IAPREFIX)) {
403 expression[i] = TokenPtr(new TokenFilterIA_PDSuboption(suboption->getRepresentation()));
404 continue;
405 }
406 }
407 boost::shared_ptr<TokenOption> option = boost::dynamic_pointer_cast<TokenOption>(expression[i]);
408 if (option) {
409 if (option->getCode() == D6O_IA_NA) {
410 expression[i] = TokenPtr(new TokenLeaseIA_NA(lease, option->getRepresentation()));
411 continue;
412 }
413 if (option->getCode() == D6O_IA_PD) {
414 expression[i] = TokenPtr(new TokenFilterIA_PD(option->getRepresentation()));
415 continue;
416 }
417 }
418 }
419}
420
429void filterLeaseIA_PD(isc::dhcp::Expression& expression, const Lease6Ptr& lease) {
430 for (size_t i = 0; i < expression.size(); ++i) {
431 boost::shared_ptr<TokenSubOption> suboption = boost::dynamic_pointer_cast<TokenSubOption>(expression[i]);
432 if (suboption) {
433 if ((suboption->getCode() == D6O_IA_NA) && (suboption->getSubCode() == D6O_IAADDR)) {
434 expression[i] = TokenPtr(new TokenFilterIA_NASuboption(suboption->getRepresentation()));
435 continue;
436 }
437 if ((suboption->getCode() == D6O_IA_PD) && (suboption->getSubCode() == D6O_IAPREFIX)) {
438 expression[i] = TokenPtr(new TokenLeaseIA_PDSuboption(lease, suboption->getRepresentation()));
439 continue;
440 }
441 }
442 boost::shared_ptr<TokenOption> option = boost::dynamic_pointer_cast<TokenOption>(expression[i]);
443 if (option) {
444 if (option->getCode() == D6O_IA_NA) {
445 expression[i] = TokenPtr(new TokenFilterIA_NA(option->getRepresentation()));
446 continue;
447 }
448 if (option->getCode() == D6O_IA_PD) {
449 expression[i] = TokenPtr(new TokenLeaseIA_PD(lease, option->getRepresentation()));
450 continue;
451 }
452 }
453 }
454}
455
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
487 auto expression = LegalLogMgrFactory::instance(handle.getCurrentLibrary())->getRequestFormatExpression();
488 if (expression && query) {
489 replaceTokensForLease(expression, lease);
490
491 value = evaluateString(*expression, *query);
492 using_custom_format = true;
493 }
494
495 expression = LegalLogMgrFactory::instance(handle.getCurrentLibrary())->getResponseFormatExpression();
496 if (expression && response) {
497 replaceTokensForLease(expression, lease);
498
499 value += evaluateString(*expression, *response);
500 using_custom_format = true;
501 }
502
503 return (using_custom_format);
504}
505
541/// @param lease DHCPv6 lease for which the entry should be created
542/// @param action Kind of event to log.
543std::string genLease6Entry(CalloutHandle& handle,
544 const Pkt6Ptr& query,
545 const Pkt6Ptr& response,
546 const Lease6Ptr& lease,
547 const Action& action) {
548 std::string value;
549 if (getCustomEntry(handle, query, response, lease, value)) {
550 return (value);
551 }
552
553 std::stringstream stream;
554
555 // <address>
556 if (lease->type_ != Lease::TYPE_PD) {
557 stream << "Address: " << lease->addr_;
558 } else {
559 stream << "Prefix: " << lease->addr_ << "/" << static_cast<int>(lease->prefixlen_);
560 }
561
562 stream << " has been " << actionToVerb(action);
563
564 if (action != Action::RELEASE) {
565 // <duration>
566 stream << " for " << LegalLogMgr::genDurationString(lease->valid_lft_) << " to";
567 } else {
568 stream << " from";
569 }
570
571 // <device-id>
572 stream << " a device with DUID: " << lease->duid_->toText();
573
574 if (lease->hwaddr_) {
575 stream << " and hardware address: " << lease->hwaddr_->toText()
576 << " (from " << hwaddrSourceToString(lease->hwaddr_->source_) << ")";
577 }
578
579 // Is it via relay(s)?
580 if (query->relay_info_.size()) {
581 const Pkt6::RelayInfo& server_relay = query->relay_info_[0];
582 stream << " connected via relay at address: " << server_relay.peeraddr_.toText()
583 << " for client on link address: " << server_relay.linkaddr_.toText()
584 << ", hop count: " << static_cast<int>(server_relay.hop_count_);
585
586 std::ostringstream idstream;
587 // Look for the remote-id option
588 OptionPtr opt = query->getAnyRelayOption(D6O_REMOTE_ID,
590 if (opt) {
591 const OptionBuffer id = opt->getData();
592 if (!id.empty()) {
593 idstream << "remote-id: " << LegalLogMgr::vectorHexDump(id);
594
595 if (str::isPrintable(id)) {
596 idstream << " (" << LegalLogMgr::vectorDump(id) << ")";
597 }
598 }
599 }
600
601 // Look for the subscriber-id option
602 opt = query->getAnyRelayOption(D6O_SUBSCRIBER_ID,
604 if (opt) {
605 const OptionBuffer id = opt->getData();
606 if (!id.empty()) {
607 if (!idstream.str().empty()) {
608 idstream << " and ";
609 }
610
611 idstream << "subscriber-id: " << LegalLogMgr::vectorHexDump(id);
612
613 if (str::isPrintable(id)) {
614 idstream << " (" << LegalLogMgr::vectorDump(id) << ")";
615 }
616 }
617 }
618
619 if (!idstream.str().empty()) {
620 stream << ", identified by " << idstream.str();
621 }
622
623 // Look for the interface-id option
624 std::ostringstream location;
625 opt = query->getAnyRelayOption(D6O_INTERFACE_ID,
627 if (opt) {
628 const OptionBuffer id = opt->getData();
629 if (!id.empty()) {
630 if (!idstream.str().empty()) {
631 idstream << " and ";
632 }
633
634 location << "interface-id: " << LegalLogMgr::vectorHexDump(id);
635
636 if (str::isPrintable(id)) {
637 location << " (" << LegalLogMgr::vectorDump(id) << ")";
638 }
639 }
640 }
641
642 if (!location.str().empty()) {
643 stream << ", connected at location " << location.str();
644 }
645
646 }
647
648 ConstElementPtr ctx = lease->getContext();
649 if (ctx) {
650 stream << ", context: " << ctx->str();
651 }
652
653 return (stream.str());
654}
655
671///
672/// @return returns 0 upon success, non-zero otherwise
673int legalLog6Handler(CalloutHandle& handle, const Action& action) {
676 return (1);
677 }
678
679 // Fetch the client's packet and the lease callout arguments.
680 Pkt6Ptr query;
681 handle.getArgument("query6", query);
682
683 Pkt6Ptr response;
684 handle.getArgument("response6", response);
685
686 Lease6Ptr lease;
687 handle.getContext("lease6", lease);
688
689 if (!lease) {
690 return (0);
691 }
692
693 ConstCfgSubnets6Ptr cfg = CfgMgr::instance().getCurrentCfg()->getCfgSubnets6();
694 try {
695 ConstSubnet6Ptr subnet = cfg->getBySubnetId(lease->subnet_id_);
696
697 if (!isLoggingDisabled(subnet)) {
698 LegalLogMgrFactory::instance(handle.getCurrentLibrary())->writeln(genLease6Entry(handle, query, response,
699 lease, action),
700 genLease6Addr(lease));
701 }
702
703 } catch (const std::exception& ex) {
705 .arg(ex.what());
706 return (1);
707 }
708
709 return (0);
710}
711
712// Functions accessed by the hooks framework use C linkage to avoid the name
713// mangling that accompanies use of the C++ compiler as well as to avoid
714// issues related to namespaces.
715extern "C" {
716
722///
723/// @return 0 upon success, non-zero otherwise.
724int pkt6_receive(CalloutHandle& handle) {
725 handle.setContext("lease6", Lease4Ptr());
726 handle.setContext("leases6", Lease6CollectionPtr());
727 handle.setContext("deleted_leases6", Lease6CollectionPtr());
728 return (0);
729}
730
737///
738/// @return 0 upon success, non-zero otherwise.
739int leases6_committed(CalloutHandle& handle) {
741 if (status == CalloutHandle::NEXT_STEP_DROP ||
743 return (0);
744 }
745
746 Lease6CollectionPtr leases;
747 handle.getArgument("leases6", leases);
748 handle.setContext("leases6", leases);
749
750 Lease6CollectionPtr deleted_leases;
751 handle.getArgument("deleted_leases6", deleted_leases);
752 handle.setContext("deleted_leases6", deleted_leases);
753 return (0);
754}
755
762///
763/// @return 0 upon success, non-zero otherwise.
764int pkt6_send(CalloutHandle& handle) {
766 if (status == CalloutHandle::NEXT_STEP_DROP ||
768 return (0);
769 }
770
771 Lease6CollectionPtr leases;
772 handle.getContext("leases6", leases);
773
774 int current = 0;
775 int result = current;
776
777 if (leases) {
778 for (auto const& lease : *leases) {
779 handle.setContext("lease6", lease);
780 current = legalLog6Handler(handle, Action::ASSIGN);
781 if (current) {
782 result = current;
783 }
784 }
785 }
786
787 handle.getContext("deleted_leases6", leases);
788
789 if (leases) {
790 for (auto const& lease : *leases) {
791 handle.setContext("lease6", lease);
792 current = legalLog6Handler(handle, Action::RELEASE);
793 if (current) {
794 result = current;
795 }
796 }
797 }
798
799 return (result);
800}
801
808///
809/// @return 0 upon success, non-zero otherwise.
810int lease6_release(CalloutHandle& handle) {
812 if (status == CalloutHandle::NEXT_STEP_DROP ||
814 return (0);
815 }
816
817 Lease6Ptr lease;
818 handle.getArgument("lease6", lease);
819
821 handle.setContext("leases6", leases);
822
823 Lease6CollectionPtr deleted_leases(new Lease6Collection());
824 deleted_leases->push_back(lease);
825 handle.setContext("deleted_leases6", deleted_leases);
826
827 return (0);
828}
829
836///
837/// @return 0 upon success, non-zero otherwise.
838int lease6_decline(CalloutHandle& handle) {
840 if (status == CalloutHandle::NEXT_STEP_DROP ||
842 return (0);
843 }
844
845 Lease6Ptr lease;
846 handle.getArgument("lease6", lease);
847
849 handle.setContext("leases6", leases);
850
851 Lease6CollectionPtr deleted_leases(new Lease6Collection());
852 deleted_leases->push_back(lease);
853 handle.setContext("deleted_leases6", deleted_leases);
854
855 return (0);
856}
857
858} // 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
static LegalLogMgrPtr & instance(ManagerID id=0)
Returns the forensic backend manager with specified ID.
static std::string vectorHexDump(const std::vector< uint8_t > &bytes, const std::string &delimiter=":")
Creates a string of hex digit pairs from a vector of bytes.
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 TokenSubOption 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 TokenSubOption 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 TokenSubOption 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 TokenSubOption 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:403
RepresentationType
Token representation type.
Definition token.h:413
TokenOption(const uint16_t option_code, const RepresentationType &rep_type)
Constructor that takes an option code as a parameter.
Definition token.h:426
virtual unsigned evaluate(Pkt &pkt, ValueStack &values)
This is a method for evaluating a packet.
Definition token.cc:1416
TokenSubOption(const uint16_t option_code, const uint16_t sub_option_code, const RepresentationType &rep_type)
Constructor that takes an option and sub-option codes as parameter.
Definition token.h:1337
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
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 and TokenSubOption expression tokens for all IA_NA and IA_PD options and sub-opti...
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 and TokenSubOption expression tokens with the IA_NA (3) option containing the OPT...
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 and TokenSubOption expression tokens with the IA_PD (25) option containing the OP...
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_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:29
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:623
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.
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