Kea 3.3.3
client_attribute.cc
Go to the documentation of this file.
1// Copyright (C) 2023-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 <util/encode/encode.h>
11#include <util/str.h>
12
13#include <cctype>
14#include <limits>
15#include <sstream>
16
17#include <boost/lexical_cast.hpp>
18
19#include <radius_log.h>
20
21using namespace isc;
22using namespace isc::asiolink;
23using namespace isc::data;
24using namespace isc::util;
25using namespace std;
26
27namespace isc {
28namespace radius {
29
31Attribute::fromText(const AttrDefPtr& def, const string& value) {
32 if (!def) {
33 isc_throw(BadValue, "null attribute definition");
34 }
35 if (value.empty()) {
36 isc_throw(BadValue, "empty attribute value");
37 }
38 AttributePtr attr = fromText0(def, value);
39 if (def->vendor_ == 0) {
40 return (attr);
41 }
42 // Encapsulate into a Vendor-Specific attribute.
43 const vector<uint8_t> vsa_data = attr->toBytes();
44 return (fromVsa(PW_VENDOR_SPECIFIC, def->vendor_, vsa_data));
45}
46
48Attribute::fromText0(const AttrDefPtr& def, const string& value) {
49 switch (static_cast<uint8_t>(def->value_type_)) {
50 case PW_TYPE_STRING:
51 return (AttrString::fromText(def->type_, value));
52 case PW_TYPE_INTEGER:
53 if (!isdigit(value[0])) {
54 IntCstDefPtr ic_def =
55 AttrDefs::instance().getByName(def->type_, value,
56 def->vendor_);
57 if (ic_def) {
58 return (fromInt(def->type_, ic_def->value_));
59 }
60 }
61 return (AttrInt::fromText(def->type_, value));
62 case PW_TYPE_IPADDR:
63 return (AttrIpAddr::fromText(def->type_, value));
65 return (AttrIpv6Addr::fromText(def->type_, value));
67 return (AttrIpv6Prefix::fromText(def->type_, value));
68 case PW_TYPE_VSA:
69 return (AttrVsa::fromText(def->type_, value));
70 default:
71 // Impossible case.
72 isc_throw(OutOfRange, "unknown value type "
73 << static_cast<unsigned>(def->value_type_));
74 }
75}
76
78Attribute::fromBytes(const vector<uint8_t>& bytes) {
79 // Checked by caller.
80 if (bytes.size() < 2) {
81 isc_throw(BadValue, "too short byte argument");
82 }
83 uint8_t type = bytes[0];
84 uint8_t len = bytes[1];
85 // Checked by caller.
86 if (len != bytes.size()) {
87 isc_throw(BadValue, "bad byte argument length " << bytes.size()
88 << " != " << static_cast<unsigned>(len));
89 }
90 vector<uint8_t> value;
91 value.resize(len - 2);
92 if (value.size() > 0) {
93 memmove(&value[0], &bytes[2], value.size());
94 }
96 if (!def) {
97 return (AttributePtr());
98 }
99 return (Attribute::fromBytes(def, value));
100}
101
103Attribute::fromBytes(const AttrDefPtr& def, const vector<uint8_t>& value) {
104 if (!def) {
105 isc_throw(BadValue, "null attribute definition");
106 }
107 if (value.empty()) {
108 isc_throw(BadValue, "empty attribute value");
109 }
110 AttributePtr attr = fromBytes0(def, value);
111 if (def->vendor_ == 0) {
112 return (attr);
113 }
114 // Encapsulate into a Vendor-Specific attribute.
115 const vector<uint8_t> vsa_data = attr->toBytes();
116 return (fromVsa(PW_VENDOR_SPECIFIC, def->vendor_, vsa_data));
117}
118
120Attribute::fromBytes0(const AttrDefPtr& def, const vector<uint8_t>& value) {
121 switch (static_cast<uint8_t>(def->value_type_)) {
122 case PW_TYPE_STRING:
123 return (AttrString::fromBytes(def->type_, value));
124 case PW_TYPE_INTEGER:
125 return (AttrInt::fromBytes(def->type_, value));
126 case PW_TYPE_IPADDR:
127 return (AttrIpAddr::fromBytes(def->type_, value));
128 case PW_TYPE_IPV6ADDR:
129 return (AttrIpv6Addr::fromBytes(def->type_, value));
131 return (AttrIpv6Prefix::fromBytes(def->type_, value));
132 case PW_TYPE_VSA:
133 return (AttrVsa::fromBytes(def->type_, value));
134 default:
135 // Impossible case.
136 isc_throw(OutOfRange, "unknown value type "
137 << static_cast<unsigned>(def->value_type_));
138 }
139}
140
142Attribute::fromString(const uint8_t type, const string& value) {
143 if (value.empty()) {
144 isc_throw(BadValue, "empty attribute value");
145 }
146 return (AttributePtr(new AttrString(type, value)));
147}
148
150Attribute::fromBinary(const uint8_t type, const vector<uint8_t>& value) {
151 if (value.empty()) {
152 isc_throw(BadValue, "empty attribute value");
153 }
154 return (AttributePtr(new AttrString(type, value)));
155}
156
158Attribute::fromInt(const uint8_t type, const uint32_t value) {
159 return (AttributePtr(new AttrInt(type, value)));
160}
161
163Attribute::fromIpAddr(const uint8_t type, const IOAddress& value) {
164 return (AttributePtr(new AttrIpAddr(type, value)));
165}
166
168Attribute::fromIpv6Addr(const uint8_t type, const IOAddress& value) {
169 return (AttributePtr(new AttrIpv6Addr(type, value)));
170}
171
173Attribute::fromIpv6Prefix(const uint8_t type, const uint8_t len,
174 const IOAddress& value) {
175 return (AttributePtr(new AttrIpv6Prefix(type, len, value)));
176}
177
179Attribute::fromVsa(const uint8_t type, const uint32_t vendor,
180 const std::string& value) {
181 return (AttributePtr(new AttrVsa(type, vendor, value)));
182}
183
185Attribute::fromVsa(const uint8_t type, const uint32_t vendor,
186 const std::vector<uint8_t>& value) {
187 return (AttributePtr(new AttrVsa(type, vendor, value)));
188}
189
190string
192 isc_throw(TypeError, "the attribute value type must be string, not "
194}
195
196vector<uint8_t>
198 isc_throw(TypeError, "the attribute value type must be string, not "
200}
201
202uint32_t
204 isc_throw(TypeError, "the attribute value type must be integer, not "
206}
207
210 isc_throw(TypeError, "the attribute value type must be ipaddr, not "
212}
213
216 isc_throw(TypeError, "the attribute value type must be ipv6addr, not "
218}
219
222 isc_throw(TypeError, "the attribute value type must be ipv6prefix, not "
224}
225
226uint8_t
228 isc_throw(TypeError, "the attribute value type must be ipv6prefix, not "
230}
231
232uint32_t
234 isc_throw(TypeError, "the attribute value type must be vsa, not "
236}
237
238std::vector<uint8_t>
240 isc_throw(TypeError, "the attribute value type must be vsa, not "
242}
243
244AttrString::AttrString(const uint8_t type, const vector<uint8_t>& value)
245 : Attribute(type), value_() {
246 if (value.empty()) {
247 isc_throw(BadValue, "value is empty");
248 }
249 if (value.size() > MAX_STRING_LEN) {
250 isc_throw(BadValue, "value is too large " << value.size()
251 << " > " << MAX_STRING_LEN);
252 }
253 value_.resize(value.size());
254 memmove(&value_[0], &value[0], value_.size());
255}
256
258AttrString::fromText(const uint8_t type, const string& repr) {
259 if (repr.empty()) {
260 isc_throw(BadValue, "empty attribute value");
261 }
262 if (repr.size() > MAX_STRING_LEN) {
263 isc_throw(BadValue, "value is too large " << repr.size()
264 << " > " << MAX_STRING_LEN);
265 }
266 return (AttributePtr(new AttrString(type, repr)));
267}
268
270AttrString::fromBytes(const uint8_t type, const vector<uint8_t>& bytes) {
271 if (bytes.empty()) {
272 isc_throw(BadValue, "empty attribute value");
273 }
274 if (bytes.size() > MAX_STRING_LEN) {
275 isc_throw(BadValue, "value is too large " << bytes.size()
276 << " > " << MAX_STRING_LEN);
277 }
278 return (AttributePtr(new AttrString(type, bytes)));
279}
280
281string
282AttrString::toText(size_t indent) const {
283 ostringstream output;
284 for (size_t i = 0; i < indent; i++) {
285 output << " ";
286 }
287 output << AttrDefs::instance().getName(getType()) << '=';
288 if (str::isPrintable(value_)) {
289 output << "'" << value_ << "'";
290 } else {
291 vector<uint8_t> binary;
292 binary.resize(value_.size());
293 if (binary.size() > 0) {
294 memmove(&binary[0], value_.c_str(), binary.size());
295 }
296 output << "0x" << encode::encodeHex(binary);
297 }
298 return (output.str());
299}
300
301vector<uint8_t>
303 vector<uint8_t> output;
304 output.resize(2 + getValueLen());
305 output[0] = getType();
306 output[1] = 2 + getValueLen();
307 if (output.size() > 2) {
308 memmove(&output[2], &value_[0], output.size() - 2);
309 }
310 return (output);
311}
312
313vector<uint8_t>
315 vector<uint8_t> binary;
316 binary.resize(getValueLen());
317 if (binary.size() > 0) {
318 memmove(&binary[0], &value_[0], binary.size());
319 }
320 return (binary);
321}
322
327 if (def) {
328 output->set("name", Element::create(def->name_));
329 }
330 output->set("type", Element::create(static_cast<int>(getType())));
331 if (str::isPrintable(value_)) {
332 output->set("data", Element::create(value_));
333 } else {
334 vector<uint8_t> binary;
335 binary.resize(value_.size());
336 if (binary.size() > 0) {
337 memmove(&binary[0], value_.c_str(), binary.size());
338 }
339 string raw = encode::encodeHex(binary);
340 output->set("raw", Element::create(raw));
341 }
342 return (output);
343}
344
346AttrInt::fromText(const uint8_t type, const string& repr) {
347 if (repr.empty()) {
348 isc_throw(BadValue, "empty attribute value");
349 }
350 try {
351 int64_t val = boost::lexical_cast<int64_t>(repr);
352 if ((val < numeric_limits<int32_t>::min()) ||
353 (val > numeric_limits<uint32_t>::max())) {
354 isc_throw(BadValue, "not 32 bit " << repr);
355 }
356 return (AttributePtr(new AttrInt(type, static_cast<uint32_t>(val))));
357 } catch (...) {
359 .arg(unsigned(type))
360 .arg(AttrDefs::instance().getName(type))
361 .arg(repr);
362 throw;
363 }
364}
365
367AttrInt::fromBytes(const uint8_t type, const vector<uint8_t>& bytes) {
368 if (bytes.size() != 4) {
369 ostringstream msg;
370 msg << "bad value length " << bytes.size() << " != 4";
372 .arg(unsigned(type))
373 .arg(AttrDefs::instance().getName(type))
374 .arg(msg.str());
375 isc_throw(BadValue, msg.str());
376 }
377 int32_t val = (static_cast<int32_t>(bytes[0])) << 24;
378 val |= (static_cast<int32_t>(bytes[1])) << 16;
379 val |= (static_cast<int32_t>(bytes[2])) << 8;
380 val |= static_cast<int32_t>(bytes[3]);
381 return (AttributePtr(new AttrInt(type, val)));
382}
383
384string
385AttrInt::toText(size_t indent) const {
386 ostringstream output;
387 for (size_t i = 0; i < indent; i++) {
388 output << " ";
389 }
390 output << AttrDefs::instance().getName(getType()) << '=';
392 if (ic_def) {
393 output << ic_def->name_;
394 } else {
395 output << value_;
396 }
397 return (output.str());
398}
399
400vector<uint8_t>
402 vector<uint8_t> output;
403 output.resize(6);
404 output[0] = getType();
405 output[1] = 6;
406 output[2] = static_cast<uint8_t>((value_ & 0xff000000U) >> 24);
407 output[3] = static_cast<uint8_t>((value_ & 0xff0000U) >> 16);
408 output[4] = static_cast<uint8_t>((value_ & 0xff00U) >> 8);
409 output[5] = static_cast<uint8_t>(value_ & 0xffU);
410 return (output);
411}
412
417 if (def) {
418 output->set("name", Element::create(def->name_));
419 }
420 output->set("type", Element::create(static_cast<int>(getType())));
421 ostringstream val;
422 val << value_;
423 output->set("data", Element::create(val.str()));
424 return (output);
425}
426
428AttrIpAddr::fromText(const uint8_t type, const string& repr) {
429 try {
430 IOAddress val(repr);
431 return (AttributePtr(new AttrIpAddr(type, val)));
432 } catch (...) {
434 .arg(unsigned(type))
435 .arg(AttrDefs::instance().getName(type))
436 .arg(repr);
437 throw;
438 }
439}
440
442AttrIpAddr::fromBytes(const uint8_t type, const vector<uint8_t>& bytes) {
443 if (bytes.size() != 4) {
444 ostringstream msg;
445 msg << "bad value length " << bytes.size() << " != 4";
447 .arg(unsigned(type))
448 .arg(AttrDefs::instance().getName(type))
449 .arg(msg.str());
450 isc_throw(BadValue, msg.str());
451 }
452 IOAddress val = IOAddress::fromBytes(AF_INET, &bytes[0]);
453 return (AttributePtr(new AttrIpAddr(type, val)));
454}
455
456string
457AttrIpAddr::toText(size_t indent) const {
458 ostringstream output;
459 for (size_t i = 0; i < indent; i++) {
460 output << " ";
461 }
462 output << AttrDefs::instance().getName(getType()) << '='
463 << value_.toText();
464 return (output.str());
465}
466
467vector<uint8_t>
469 vector<uint8_t> output;
470 output.resize(6);
471 output[0] = getType();
472 output[1] = 6;
473 vector<uint8_t> binary = value_.toBytes();
474 memmove(&output[2], &binary[0], output.size() - 2);
475 return (output);
476}
477
482 if (def) {
483 output->set("name", Element::create(def->name_));
484 }
485 output->set("type", Element::create(static_cast<int>(getType())));
486 ostringstream val;
487 val << value_.toText();
488 output->set("data", Element::create(val.str()));
489 return (output);
490}
491
493AttrIpv6Addr::fromText(const uint8_t type, const string& repr) {
494 try {
495 IOAddress val(repr);
496 return (AttributePtr(new AttrIpv6Addr(type, val)));
497 } catch (...) {
499 .arg(unsigned(type))
500 .arg(AttrDefs::instance().getName(type))
501 .arg(repr);
502 throw;
503 }
504}
505
507AttrIpv6Addr::fromBytes(const uint8_t type, const vector<uint8_t>& bytes) {
508 if (bytes.size() != 16) {
509 ostringstream msg;
510 msg << "bad value length " << bytes.size() << " != 16";
512 .arg(unsigned(type))
513 .arg(AttrDefs::instance().getName(type))
514 .arg(msg.str());
515 isc_throw(BadValue, msg.str());
516 }
517 IOAddress val = IOAddress::fromBytes(AF_INET6, &bytes[0]);
518 return (AttributePtr(new AttrIpv6Addr(type, val)));
519}
520
521string
522AttrIpv6Addr::toText(size_t indent) const {
523 ostringstream output;
524 for (size_t i = 0; i < indent; i++) {
525 output << " ";
526 }
527 output << AttrDefs::instance().getName(getType()) << '='
528 << value_.toText();
529 return (output.str());
530}
531
532vector<uint8_t>
534 vector<uint8_t> output;
535 output.resize(18);
536 output[0] = getType();
537 output[1] = 18;
538 vector<uint8_t> binary = value_.toBytes();
539 memmove(&output[2], &binary[0], output.size() - 2);
540 return (output);
541}
542
547 if (def) {
548 output->set("name", Element::create(def->name_));
549 }
550 output->set("type", Element::create(static_cast<int>(getType())));
551 ostringstream val;
552 val << value_.toText();
553 output->set("data", Element::create(val.str()));
554 return (output);
555}
556
558AttrIpv6Prefix::fromText(const uint8_t type, const string& repr) {
559 try {
560 auto pos = repr.find('/');
561 if ((pos == string::npos) ||
562 (pos == repr.size() - 1) ||
563 (pos == 0)) {
564 isc_throw(BadValue, "unable to parse prefix " << repr);
565 }
566 IOAddress val(repr.substr(0, pos));
567 int len = boost::lexical_cast<int>(repr.substr(pos + 1));
568 if ((len < numeric_limits<uint8_t>::min()) ||
569 (len > numeric_limits<uint8_t>::max())) {
570 isc_throw(BadValue, "not 8 bit prefix length " << repr);
571 }
572 return (AttributePtr(new AttrIpv6Prefix(type,
573 static_cast<uint8_t>(len),
574 val)));
575 } catch (...) {
577 .arg(unsigned(type))
578 .arg(AttrDefs::instance().getName(type))
579 .arg(repr);
580 throw;
581 }
582}
583
585AttrIpv6Prefix::fromBytes(const uint8_t type, const vector<uint8_t>& bytes) {
587 ostringstream msg;
588 if (bytes.size() < 2) {
589 msg << "bad value length " << bytes.size() << " < 2";
590 } else if (bytes.size() > 18) {
591 msg << "bad value length " << bytes.size() << " > 18";
592 } else if (bytes[1] > 128) {
593 msg << "bad prefix length " << static_cast<unsigned>(bytes[1]) << " > 128";
594 }
595 string const msg_str(msg.str());
596 if (!msg_str.empty()) {
598 .arg(static_cast<unsigned>(type))
599 .arg(AttrDefs::instance().getName(type))
600 .arg(msg.str());
601 isc_throw(BadValue, msg_str);
602 }
603 uint8_t len = bytes[1];
604 vector<uint8_t> prefix(16);
605 if (bytes.size() > 2) {
606 memmove(&prefix[0], &bytes[2], bytes.size() - 2);
607 }
608 IOAddress val = IOAddress::fromBytes(AF_INET6, &prefix[0]);
609 return (AttributePtr(new AttrIpv6Prefix(type, len, val)));
610}
611
612string
613AttrIpv6Prefix::toText(size_t indent) const {
614 ostringstream output;
615 for (size_t i = 0; i < indent; i++) {
616 output << " ";
617 }
618 output << AttrDefs::instance().getName(getType()) << '='
619 << value_.toText() << "/" << static_cast<unsigned>(len_);
620 return (output.str());
621}
622
623vector<uint8_t>
625 vector<uint8_t> output;
626 // type(1) + length(1) + reserved(1) + prefix_len(1) + prefix(16)
627 output.resize(20);
628 output[0] = getType();
629 output[1] = 20;
630 output[2] = 0;
631 output[3] = len_;
632 vector<uint8_t> binary = value_.toBytes();
633 memmove(&output[4], &binary[0], output.size() - 4);
634 return (output);
635}
636
641 if (def) {
642 output->set("name", Element::create(def->name_));
643 }
644 output->set("type", Element::create(static_cast<int>(getType())));
645 ostringstream val;
646 val << value_.toText() << "/" << static_cast<unsigned>(len_);
647 output->set("data", Element::create(val.str()));
648 return (output);
649}
650
651AttrVsa::AttrVsa(const uint8_t type, const uint32_t vendor,
652 const vector<uint8_t>& value)
653 : Attribute(type), vendor_(vendor), value_() {
654 if (value.empty()) {
655 isc_throw(BadValue, "value is empty");
656 }
657 if (value.size() > MAX_VSA_DATA_LEN) {
658 isc_throw(BadValue, "value is too large " << value.size()
659 << " > " << MAX_VSA_DATA_LEN);
660 }
661 value_.resize(value.size());
662 memmove(&value_[0], &value[0], value_.size());
663}
664
666AttrVsa::fromText(const uint8_t /* type */, const string& /* repr */) {
667 isc_throw(NotImplemented, "can't decode vsa from text");
668}
669
671AttrVsa::fromBytes(const uint8_t type, const vector<uint8_t>& bytes) {
672 if (bytes.empty()) {
673 isc_throw(BadValue, "empty attribute value");
674 }
675 if (bytes.size() < 5) {
676 isc_throw(BadValue, "value is too small " << bytes.size() << " < 5");
677 } else if (bytes.size() > MAX_STRING_LEN) {
678 isc_throw(BadValue, "value is too large " << bytes.size()
679 << " > " << MAX_STRING_LEN);
680 }
681 uint32_t vendor = bytes[0] << 24;
682 vendor |= bytes[1] << 16;
683 vendor |= bytes[2] << 8;
684 vendor |= bytes[3];
685 vector<uint8_t> value;
686 value.resize(bytes.size() - 4);
687 if (value.size() > 0) {
688 memmove(&value[0], &bytes[4], value.size());
689 }
690 return (AttributePtr(new AttrVsa(type, vendor, value)));
691}
692
693string
694AttrVsa::toText(size_t indent) const {
695 ostringstream output;
696 for (size_t i = 0; i < indent; i++) {
697 output << " ";
698 }
699 output << AttrDefs::instance().getName(getType()) << "=["
700 << vendor_ << "]";
701 vector<uint8_t> binary;
702 binary.resize(value_.size());
703 if (binary.size() > 0) {
704 memmove(&binary[0], value_.c_str(), binary.size());
705 }
706 output << "0x" << encode::encodeHex(binary);
707 return (output.str());
708}
709
710std::vector<uint8_t>
712 vector<uint8_t> output;
713 output.resize(2 + getValueLen());
714 output[0] = getType();
715 output[1] = 2 + getValueLen();
716 output[2] = (vendor_ & 0xff000000U) >> 24;
717 output[3] = (vendor_ & 0xff0000U) >> 16;
718 output[4] = (vendor_ & 0xff00U) >> 8;
719 output[5] = vendor_ & 0xffU;
720 if (output.size() > 6) {
721 memmove(&output[6], &value_[0], output.size() - 6);
722 }
723 return (output);
724}
725
726std::vector<uint8_t>
728 vector<uint8_t> binary;
729 binary.resize(value_.size());
730 if (binary.size() > 0) {
731 memmove(&binary[0], &value_[0], binary.size());
732 }
733 return (binary);
734}
735
740 if (def) {
741 output->set("name", Element::create(def->name_));
742 }
743 output->set("type", Element::create(static_cast<int>(getType())));
744 ostringstream vendor;
745 vendor << vendor_;
746 output->set("vendor", Element::create(vendor.str()));
747 vector<uint8_t> binary;
748 binary.resize(value_.size());
749 if (binary.size() > 0) {
750 memmove(&binary[0], value_.c_str(), binary.size());
751 }
752 string raw = encode::encodeHex(binary);
753 output->set("vsa-raw", Element::create(raw));
754 return (output);
755}
756
757void
758Attributes::add(const ConstAttributePtr& attr, bool back) {
759 if (!attr) {
760 return;
761 }
762 if (back) {
763 static_cast<void>(container_.push_back(attr));
764 } else {
765 static_cast<void>(container_.push_front(attr));
766 }
767}
768
769bool
770Attributes::del(const uint8_t type) {
771 auto& idx = container_.get<1>();
772 auto it = idx.find(type);
773 if (it != idx.end()) {
774 idx.erase(it);
775 return (true);
776 }
777 return (false);
778}
779
780void
782 for (auto const& it : other) {
783 add(it);
784 }
785}
786
787size_t
788Attributes::count(const uint8_t type) const {
789 auto const& idx = container_.get<1>();
790 return (idx.count(type));
791}
792
794Attributes::get(const uint8_t type) const {
795 auto const& idx = container_.get<1>();
796 auto it = idx.find(type);
797 if (it != idx.end()) {
798 return (*it);
799 } else {
800 return(ConstAttributePtr());
801 }
802}
803
804string
805Attributes::toText(size_t indent) const {
806 ostringstream output;
807 bool first = true;
808 for (auto const& it : *this) {
809 if (!first) {
810 output << ",\n";
811 } else {
812 first = false;
813 }
814 output << it->toText(indent);
815 }
816 return (output.str());
817}
818
822 for (auto const& it : *this) {
823 output->add(it->toElement());
824 }
825 return (output);
826}
827
830 Attributes attrs;
831 if (!attr_list || (attr_list->getType() != Element::list)) {
832 return (attrs);
833 }
834 for (auto const& entry : attr_list->listValue()) {
835 if (!entry || (entry->getType() != Element::map)) {
836 continue;
837 }
838 ConstElementPtr attr_type = entry->get("type");
839 if (!attr_type || (attr_type->getType() != Element::integer)) {
840 continue;
841 }
842 AttrDefPtr def = AttrDefs::instance().getByType(attr_type->intValue());
843 if (!def) {
844 continue;
845 }
846 if (def->value_type_ == PW_TYPE_STRING) {
847 ConstElementPtr raw = entry->get("raw");
848 if (raw && (raw->getType() == Element::string) &&
849 (!raw->stringValue().empty())) {
850 try {
851 vector<uint8_t> binary;
852 encode::decodeHex(raw->stringValue(), binary);
853 AttributePtr attr = Attribute::fromBytes(def, binary);
854 attrs.add(attr);
855 continue;
856 } catch (...) {
857 continue;
858 }
859 }
860 }
861 ConstElementPtr data = entry->get("data");
862 if (data && (data->getType() == Element::string) &&
863 (!data->stringValue().empty())) {
864 AttributePtr attr = Attribute::fromText(def, data->stringValue());
865 attrs.add(attr);
866 continue;
867 }
868 }
869 return (attrs);
870}
871
872} // end of namespace isc::radius
873} // end of namespace isc
static ElementPtr create(const Position &pos=ZERO_POSITION())
Create a NullElement.
Definition data.cc:300
@ map
Definition data.h:160
@ integer
Definition data.h:153
@ list
Definition data.h:159
@ 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...
A generic exception that is thrown when a function is not implemented.
A generic exception that is thrown if a parameter given to a method would refer to or modify out-of-r...
A standard Data module exception that is thrown if a function is called for an Element that has a wro...
Definition data.h:37
static AttrDefs & instance()
Returns a single instance.
IntCstDefPtr getByValue(const uint8_t type, const uint32_t value, const uint32_t vendor=0) const
Get integer constant definition by attribute type and value.
std::string getName(const uint8_t type, const uint32_t vendor=0) const
Get attribute name.
AttrDefPtr getByName(const std::string &name, const uint32_t vendor=0) const
Get attribute definition by name and vendor.
AttrDefPtr getByType(const uint8_t type, const uint32_t vendor=0) const
Get attribute definition by type and vendor.
RADIUS attribute holding integers.
static AttributePtr fromText(const uint8_t type, const std::string &repr)
From text.
virtual std::vector< uint8_t > toBytes() const override
To bytes.
virtual data::ElementPtr toElement() const override
Unparse attribute.
virtual std::string toText(size_t indent=0) const override
Returns text representation of the attribute.
AttrInt(const uint8_t type, const int32_t value)
Constructor (signed).
static AttributePtr fromBytes(const uint8_t type, const std::vector< uint8_t > &bytes)
From bytes.
RADIUS attribute holding IPv4 addresses.
AttrIpAddr(const uint8_t type, const asiolink::IOAddress &value)
Constructor.
virtual data::ElementPtr toElement() const override
Unparse attribute.
virtual std::vector< uint8_t > toBytes() const override
To bytes.
static AttributePtr fromText(const uint8_t type, const std::string &repr)
From text.
static AttributePtr fromBytes(const uint8_t type, const std::vector< uint8_t > &bytes)
From bytes.
virtual std::string toText(size_t indent=0) const override
Returns text representation of the attribute.
RADIUS attribute holding IPv6 addresses.
virtual std::string toText(size_t indent=0) const override
Returns text representation of the attribute.
static AttributePtr fromBytes(const uint8_t type, const std::vector< uint8_t > &bytes)
From bytes.
virtual std::vector< uint8_t > toBytes() const override
To bytes.
static AttributePtr fromText(const uint8_t type, const std::string &repr)
From text.
AttrIpv6Addr(const uint8_t type, const asiolink::IOAddress &value)
Constructor.
virtual data::ElementPtr toElement() const override
Unparse attribute.
RADIUS attribute holding IPv6 prefixes.
AttrIpv6Prefix(const uint8_t type, const uint8_t len, const asiolink::IOAddress &value)
Constructor.
virtual std::vector< uint8_t > toBytes() const override
To bytes.
virtual data::ElementPtr toElement() const override
Unparse attribute.
static AttributePtr fromText(const uint8_t type, const std::string &repr)
From text.
static AttributePtr fromBytes(const uint8_t type, const std::vector< uint8_t > &bytes)
From bytes.
virtual std::string toText(size_t indent=0) const override
Returns text representation of the attribute.
RADIUS attribute derived classes: do not use them directly outside unit tests, instead use Attribute ...
static AttributePtr fromBytes(const uint8_t type, const std::vector< uint8_t > &bytes)
From bytes.
static AttributePtr fromText(const uint8_t type, const std::string &repr)
From text.
virtual std::vector< uint8_t > toBytes() const override
To bytes.
virtual data::ElementPtr toElement() const override
Unparse attribute.
virtual std::string toText(size_t indent=0) const override
Returns text representation of the attribute.
AttrString(const uint8_t type, const std::string &value)
Constructor.
virtual std::vector< uint8_t > toBinary() const override
To binary.
virtual size_t getValueLen() const override
Value length.
friend class Attribute
Make Attribute a friend class.
RADIUS attribute holding vsa.
virtual data::ElementPtr toElement() const override
Unparse attribute.
virtual std::string toText(size_t indent=0) const override
Returns text representation of the attribute.
static AttributePtr fromBytes(const uint8_t type, const std::vector< uint8_t > &bytes)
From bytes.
friend class Attribute
Make Attribute a friend class.
static AttributePtr fromText(const uint8_t type, const std::string &repr)
From text.
virtual std::vector< uint8_t > toVsaData() const override
To vsa data.
AttrVsa(const uint8_t type, const uint32_t vendor, const std::string &value)
Constructor.
virtual size_t getValueLen() const override
Value length.
virtual std::vector< uint8_t > toBytes() const override
To bytes.
static AttributePtr fromBytes(const std::vector< uint8_t > &bytes)
Generic factories.
virtual std::string toString() const
Specific get methods.
static AttributePtr fromInt(const uint8_t type, const uint32_t value)
From integer with type.
static AttributePtr fromIpAddr(const uint8_t type, const asiolink::IOAddress &value)
From IPv4 address with type.
virtual uint32_t toInt() const
To integer.
virtual uint32_t toVendorId() const
To vendor id.
static AttributePtr fromString(const uint8_t type, const std::string &value)
From type specific factories.
uint8_t getType() const
Get type.
virtual asiolink::IOAddress toIpAddr() const
To IPv4 address.
virtual asiolink::IOAddress toIpv6Addr() const
To IPv6 address.
static AttributePtr fromBinary(const uint8_t type, const std::vector< uint8_t > &value)
From binary with type.
static AttributePtr fromText(const AttrDefPtr &def, const std::string &value)
From definition generic factories.
virtual uint8_t toIpv6PrefixLen() const
To IPv6 prefix length.
static AttributePtr fromIpv6Prefix(const uint8_t type, const uint8_t len, const asiolink::IOAddress &value)
From IPv6 prefix with type.
static AttributePtr fromIpv6Addr(const uint8_t type, const asiolink::IOAddress &value)
From IPv6 address with type.
virtual asiolink::IOAddress toIpv6Prefix() const
To IPv6 prefix.
virtual AttrValueType getValueType() const =0
Get value type.
virtual std::vector< uint8_t > toBinary() const
To binary.
static AttributePtr fromVsa(const uint8_t type, const uint32_t vendor, const std::string &value)
From Vendor ID and string data with type.
virtual std::vector< uint8_t > toVsaData() const
To vsa data.
Collection of attributes.
AttributeContainer container_
The container.
std::string toText(size_t indent=0) const
Returns text representation of the collection.
void append(const Attributes &other)
Append another collection.
size_t count(const uint8_t type) const
Counts instance of the attribute in the collection.
ConstAttributePtr get(const uint8_t type) const
Get instance of the attribute in the collection.
data::ElementPtr toElement() const override
Unparse collection.
void add(const ConstAttributePtr &attr, bool back=true)
Adds instance of the attribute to the collection.
bool del(const uint8_t type)
Deletes an attribute from the collection.
static Attributes fromElement(const data::ConstElementPtr &attr_list)
Parse collection.
if(!(yy_init))
Definition d2_lexer.cc:1515
#define isc_throw(type, stream)
A shortcut macro to insert known values into exception arguments.
#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< Element > ElementPtr
Definition data.h:29
boost::shared_ptr< IntCstDef > IntCstDefPtr
Shared pointers to Integer constant definition.
const isc::log::MessageID RADIUS_IPV6PREFIX_ATTRIBUTE_FROM_BYTES_FAILED
boost::shared_ptr< const Attribute > ConstAttributePtr
const isc::log::MessageID RADIUS_IPADDR_ATTRIBUTE_FROM_BYTES_FAILED
const isc::log::MessageID RADIUS_IPV6PREFIX_ATTRIBUTE_FROM_TEXT_FAILED
boost::shared_ptr< AttrDef > AttrDefPtr
Shared pointers to Attribute definition.
string attrValueTypeToText(const AttrValueType value)
AttrValueType value -> name function.
boost::shared_ptr< Attribute > AttributePtr
const isc::log::MessageID RADIUS_IPV6ADDR_ATTRIBUTE_FROM_TEXT_FAILED
isc::log::Logger radius_logger("radius-hooks")
Radius Logger.
Definition radius_log.h:35
const isc::log::MessageID RADIUS_INTEGER_ATTRIBUTE_FROM_TEXT_FAILED
const isc::log::MessageID RADIUS_INTEGER_ATTRIBUTE_FROM_BYTES_FAILED
const isc::log::MessageID RADIUS_IPADDR_ATTRIBUTE_FROM_TEXT_FAILED
const isc::log::MessageID RADIUS_IPV6ADDR_ATTRIBUTE_FROM_BYTES_FAILED
void decodeHex(const string &encoded_str, vector< uint8_t > &output)
Decode a base16 encoded string into binary data.
Definition encode.cc:367
string encodeHex(const vector< uint8_t > &binary)
Encode binary data in the base16 format.
Definition encode.cc:361
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.