Kea 3.1.1
client_attribute.cc
Go to the documentation of this file.
1// Copyright (C) 2023-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>
8
9#include <client_attribute.h>
10#include <radius_log.h>
11#include <util/encode/encode.h>
12#include <util/str.h>
13#include <boost/lexical_cast.hpp>
14#include <cctype>
15#include <limits>
16#include <sstream>
17
18using namespace isc;
19using namespace isc::asiolink;
20using namespace isc::data;
21using namespace isc::util;
22using namespace std;
23
24namespace isc {
25namespace radius {
26
28Attribute::fromText(const string& repr) {
29 if (repr.empty()) {
30 isc_throw(BadValue, "empty text attribute");
31 }
32 string trimed = str::trim(repr);
33 if (trimed.empty()) {
34 isc_throw(BadValue, "blank text attribute '" << repr << "'");
35 }
36 size_t equal = trimed.find('=');
37 if (equal == string::npos) {
38 isc_throw(BadValue, "can't find '=' in text attribute '"
39 << repr << "'");
40 }
41 string name = str::trim(trimed.substr(0, equal));
42 if (name.empty()) {
43 isc_throw(BadValue, "empty attribute name in '" << repr << "'");
44 }
45 string value = str::trim(trimed.substr(equal + 1));
46 if (value.empty()) {
47 isc_throw(BadValue, "empty attribute value in '" << repr << "'");
48 }
50 if (!def) {
51 isc_throw(NotFound, "can't find attribute definition for '"
52 << name << "'");
53 }
54 return (Attribute::fromText(def, value));
55}
56
58Attribute::fromText(const AttrDefPtr& def, const string& value) {
59 if (!def) {
60 isc_throw(BadValue, "null attribute definition");
61 }
62 if (value.empty()) {
63 isc_throw(BadValue, "empty attribute value");
64 }
65 switch (static_cast<uint8_t>(def->value_type_)) {
66 case PW_TYPE_STRING:
67 return (AttrString::fromText(def->type_, value));
68 case PW_TYPE_INTEGER:
69 if (!isdigit(value[0])) {
70 IntCstDefPtr ic_def =
71 AttrDefs::instance().getByName(def->type_, value);
72 if (ic_def) {
73 return (fromInt(def->type_, ic_def->value_));
74 }
75 }
76 return (AttrInt::fromText(def->type_, value));
77 case PW_TYPE_IPADDR:
78 return (AttrIpAddr::fromText(def->type_, value));
80 return (AttrIpv6Addr::fromText(def->type_, value));
82 return (AttrIpv6Prefix::fromText(def->type_, value));
83 default:
84 // Impossible case.
85 isc_throw(OutOfRange, "unknown value type "
86 << static_cast<unsigned>(def->value_type_));
87 }
88}
89
91Attribute::fromBytes(const vector<uint8_t>& bytes) {
92 // Checked by caller.
93 if (bytes.size() < 2) {
94 isc_throw(BadValue, "too short byte argument");
95 }
96 uint8_t type = bytes[0];
97 uint8_t len = bytes[1];
98 // Checked by caller.
99 if (len != bytes.size()) {
100 isc_throw(BadValue, "bad byte argument length " << bytes.size()
101 << " != " << static_cast<unsigned>(len));
102 }
103 vector<uint8_t> value;
104 value.resize(len - 2);
105 if (value.size() > 0) {
106 memmove(&value[0], &bytes[2], value.size());
107 }
109 if (!def) {
110 return (AttributePtr());
111 }
112 return (Attribute::fromBytes(def, value));
113}
114
116Attribute::fromBytes(const AttrDefPtr& def, const vector<uint8_t>& value) {
117 if (!def) {
118 isc_throw(BadValue, "null attribute definition");
119 }
120 if (value.empty()) {
121 isc_throw(BadValue, "empty attribute value");
122 }
123 switch (static_cast<uint8_t>(def->value_type_)) {
124 case PW_TYPE_STRING:
125 return (AttrString::fromBytes(def->type_, value));
126 case PW_TYPE_INTEGER:
127 return (AttrInt::fromBytes(def->type_, value));
128 case PW_TYPE_IPADDR:
129 return (AttrIpAddr::fromBytes(def->type_, value));
130 case PW_TYPE_IPV6ADDR:
131 return (AttrIpv6Addr::fromBytes(def->type_, value));
133 return (AttrIpv6Prefix::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
178string
180 isc_throw(TypeError, "the attribute value type must be string, not "
182}
183
184vector<uint8_t>
186 isc_throw(TypeError, "the attribute value type must be string, not "
188}
189
190uint32_t
192 isc_throw(TypeError, "the attribute value type must be integer, not "
194}
195
198 isc_throw(TypeError, "the attribute value type must be ipaddr, not "
200}
201
204 isc_throw(TypeError, "the attribute value type must be ipv6addr, not "
206}
207
210 isc_throw(TypeError, "the attribute value type must be ipv6prefix, not "
212}
213
214uint8_t
216 isc_throw(TypeError, "the attribute value type must be ipv6prefix, not "
218}
219
220AttrString::AttrString(const uint8_t type, const vector<uint8_t>& value)
221 : Attribute(type), value_() {
222 if (value.empty()) {
223 isc_throw(BadValue, "value is empty");
224 }
225 if (value.size() > MAX_STRING_LEN) {
226 isc_throw(BadValue, "value is too large " << value.size()
227 << " > " << MAX_STRING_LEN);
228 }
229 value_.resize(value.size());
230 memmove(&value_[0], &value[0], value_.size());
231}
232
234AttrString::fromText(const uint8_t type, const string& repr) {
235 if (repr.empty()) {
236 isc_throw(BadValue, "empty attribute value");
237 }
238 if (repr.size() > MAX_STRING_LEN) {
239 isc_throw(BadValue, "value is too large " << repr.size()
240 << " > " << MAX_STRING_LEN);
241 }
242 return (AttributePtr(new AttrString(type, repr)));
243}
244
246AttrString::fromBytes(const uint8_t type, const vector<uint8_t>& bytes) {
247 if (bytes.empty()) {
248 isc_throw(BadValue, "empty attribute value");
249 }
250 if (bytes.size() > MAX_STRING_LEN) {
251 isc_throw(BadValue, "value is too large " << bytes.size()
252 << " > " << MAX_STRING_LEN);
253 }
254 return (AttributePtr(new AttrString(type, bytes)));
255}
256
257string
258AttrString::toText(size_t indent) const {
259 ostringstream output;
260 for (size_t i = 0; i < indent; i++) {
261 output << " ";
262 }
263 output << AttrDefs::instance().getName(getType()) << '=' << value_;
264 return (output.str());
265}
266
267vector<uint8_t>
269 vector<uint8_t> output;
270 output.resize(2 + getValueLen());
271 output[0] = getType();
272 output[1] = 2 + getValueLen();
273 memmove(&output[2], &value_[0], output.size() - 2);
274 return (output);
275}
276
277vector<uint8_t>
279 vector<uint8_t> binary;
280 binary.resize(getValueLen());
281 if (binary.size() > 0) {
282 memmove(&binary[0], &value_[0], binary.size());
283 }
284 return (binary);
285}
286
291 if (def) {
292 output->set("name", Element::create(def->name_));
293 }
294 output->set("type", Element::create(static_cast<int>(getType())));
295 if (str::isPrintable(value_)) {
296 output->set("data", Element::create(value_));
297 } else {
298 vector<uint8_t> binary;
299 binary.resize(value_.size());
300 if (binary.size() > 0) {
301 memmove(&binary[0], value_.c_str(), binary.size());
302 }
303 string raw = encode::encodeHex(binary);
304 output->set("raw", Element::create(raw));
305 }
306 return (output);
307}
308
310AttrInt::fromText(const uint8_t type, const string& repr) {
311 if (repr.empty()) {
312 isc_throw(BadValue, "empty attribute value");
313 }
314 try {
315 int64_t val = boost::lexical_cast<int64_t>(repr);
316 if ((val < numeric_limits<int32_t>::min()) ||
317 (val > numeric_limits<uint32_t>::max())) {
318 isc_throw(BadValue, "not 32 bit " << repr);
319 }
320 return (AttributePtr(new AttrInt(type, static_cast<uint32_t>(val))));
321 } catch (...) {
323 .arg(unsigned(type))
324 .arg(AttrDefs::instance().getName(type))
325 .arg(repr);
326 throw;
327 }
328}
329
331AttrInt::fromBytes(const uint8_t type, const vector<uint8_t>& bytes) {
332 if (bytes.size() != 4) {
333 ostringstream msg;
334 msg << "bad value length " << bytes.size() << " != 4";
336 .arg(unsigned(type))
337 .arg(AttrDefs::instance().getName(type))
338 .arg(msg.str());
339 isc_throw(BadValue, msg.str());
340 }
341 int32_t val = (static_cast<int32_t>(bytes[0])) << 24;
342 val |= (static_cast<int32_t>(bytes[1])) << 16;
343 val |= (static_cast<int32_t>(bytes[2])) << 8;
344 val |= static_cast<int32_t>(bytes[3]);
345 return (AttributePtr(new AttrInt(type, val)));
346}
347
348string
349AttrInt::toText(size_t indent) const {
350 ostringstream output;
351 for (size_t i = 0; i < indent; i++) {
352 output << " ";
353 }
354 output << AttrDefs::instance().getName(getType()) << '=';
356 if (ic_def) {
357 output << ic_def->name_;
358 } else {
359 output << value_;
360 }
361 return (output.str());
362}
363
364vector<uint8_t>
366 vector<uint8_t> output;
367 output.resize(6);
368 output[0] = getType();
369 output[1] = 6;
370 output[2] = static_cast<uint8_t>((value_ & 0xff000000U) >> 24);
371 output[3] = static_cast<uint8_t>((value_ & 0xff0000U) >> 16);
372 output[4] = static_cast<uint8_t>((value_ & 0xff00U) >> 8);
373 output[5] = static_cast<uint8_t>(value_ & 0xffU);
374 return (output);
375}
376
381 if (def) {
382 output->set("name", Element::create(def->name_));
383 }
384 output->set("type", Element::create(static_cast<int>(getType())));
385 ostringstream val;
386 val << value_;
387 output->set("data", Element::create(val.str()));
388 return (output);
389}
390
392AttrIpAddr::fromText(const uint8_t type, const string& repr) {
393 try {
394 IOAddress val(repr);
395 return (AttributePtr(new AttrIpAddr(type, val)));
396 } catch (...) {
398 .arg(unsigned(type))
399 .arg(AttrDefs::instance().getName(type))
400 .arg(repr);
401 throw;
402 }
403}
404
406AttrIpAddr::fromBytes(const uint8_t type, const vector<uint8_t>& bytes) {
407 if (bytes.size() != 4) {
408 ostringstream msg;
409 msg << "bad value length " << bytes.size() << " != 4";
411 .arg(unsigned(type))
412 .arg(AttrDefs::instance().getName(type))
413 .arg(msg.str());
414 isc_throw(BadValue, msg.str());
415 }
416 IOAddress val = IOAddress::fromBytes(AF_INET, &bytes[0]);
417 return (AttributePtr(new AttrIpAddr(type, val)));
418}
419
420string
421AttrIpAddr::toText(size_t indent) const {
422 ostringstream output;
423 for (size_t i = 0; i < indent; i++) {
424 output << " ";
425 }
426 output << AttrDefs::instance().getName(getType()) << '='
427 << value_.toText();
428 return (output.str());
429}
430
431vector<uint8_t>
433 vector<uint8_t> output;
434 output.resize(6);
435 output[0] = getType();
436 output[1] = 6;
437 vector<uint8_t> binary = value_.toBytes();
438 memmove(&output[2], &binary[0], output.size() - 2);
439 return (output);
440}
441
446 if (def) {
447 output->set("name", Element::create(def->name_));
448 }
449 output->set("type", Element::create(static_cast<int>(getType())));
450 ostringstream val;
451 val << value_.toText();
452 output->set("data", Element::create(val.str()));
453 return (output);
454}
455
457AttrIpv6Addr::fromText(const uint8_t type, const string& repr) {
458 try {
459 IOAddress val(repr);
460 return (AttributePtr(new AttrIpv6Addr(type, val)));
461 } catch (...) {
463 .arg(unsigned(type))
464 .arg(AttrDefs::instance().getName(type))
465 .arg(repr);
466 throw;
467 }
468}
469
471AttrIpv6Addr::fromBytes(const uint8_t type, const vector<uint8_t>& bytes) {
472 if (bytes.size() != 16) {
473 ostringstream msg;
474 msg << "bad value length " << bytes.size() << " != 16";
476 .arg(unsigned(type))
477 .arg(AttrDefs::instance().getName(type))
478 .arg(msg.str());
479 isc_throw(BadValue, msg.str());
480 }
481 IOAddress val = IOAddress::fromBytes(AF_INET6, &bytes[0]);
482 return (AttributePtr(new AttrIpv6Addr(type, val)));
483}
484
485string
486AttrIpv6Addr::toText(size_t indent) const {
487 ostringstream output;
488 for (size_t i = 0; i < indent; i++) {
489 output << " ";
490 }
491 output << AttrDefs::instance().getName(getType()) << '='
492 << value_.toText();
493 return (output.str());
494}
495
496vector<uint8_t>
498 vector<uint8_t> output;
499 output.resize(18);
500 output[0] = getType();
501 output[1] = 18;
502 vector<uint8_t> binary = value_.toBytes();
503 memmove(&output[2], &binary[0], output.size() - 2);
504 return (output);
505}
506
511 if (def) {
512 output->set("name", Element::create(def->name_));
513 }
514 output->set("type", Element::create(static_cast<int>(getType())));
515 ostringstream val;
516 val << value_.toText();
517 output->set("data", Element::create(val.str()));
518 return (output);
519}
520
522AttrIpv6Prefix::fromText(const uint8_t type, const string& repr) {
523 try {
524 auto pos = repr.find('/');
525 if ((pos == string::npos) ||
526 (pos == repr.size() - 1) ||
527 (pos == 0)) {
528 isc_throw(BadValue, "unable to parse prefix " << repr);
529 }
530 IOAddress val(repr.substr(0, pos));
531 int len = boost::lexical_cast<int>(repr.substr(pos + 1));
532 if ((len < numeric_limits<uint8_t>::min()) ||
533 (len > numeric_limits<uint8_t>::max())) {
534 isc_throw(BadValue, "not 8 bit prefix length " << repr);
535 }
536 return (AttributePtr(new AttrIpv6Prefix(type,
537 static_cast<uint8_t>(len),
538 val)));
539 } catch (...) {
541 .arg(unsigned(type))
542 .arg(AttrDefs::instance().getName(type))
543 .arg(repr);
544 throw;
545 }
546}
547
549AttrIpv6Prefix::fromBytes(const uint8_t type, const vector<uint8_t>& bytes) {
551 ostringstream msg;
552 if (bytes.size() < 2) {
553 msg << "bad value length " << bytes.size() << " < 2";
554 } else if (bytes.size() > 18) {
555 msg << "bad value length " << bytes.size() << " > 18";
556 } else if (bytes[1] > 128) {
557 msg << "bad prefix length " << static_cast<unsigned>(bytes[1]) << " > 128";
558 }
559 string const msg_str(msg.str());
560 if (!msg_str.empty()) {
562 .arg(static_cast<unsigned>(type))
563 .arg(AttrDefs::instance().getName(type))
564 .arg(msg.str());
565 isc_throw(BadValue, msg_str);
566 }
567 uint8_t len = bytes[1];
568 vector<uint8_t> prefix(16);
569 if (bytes.size() > 2) {
570 memmove(&prefix[0], &bytes[2], bytes.size() - 2);
571 }
572 IOAddress val = IOAddress::fromBytes(AF_INET6, &prefix[0]);
573 return (AttributePtr(new AttrIpv6Prefix(type, len, val)));
574}
575
576string
577AttrIpv6Prefix::toText(size_t indent) const {
578 ostringstream output;
579 for (size_t i = 0; i < indent; i++) {
580 output << " ";
581 }
582 output << AttrDefs::instance().getName(getType()) << '='
583 << value_.toText() << "/" << static_cast<unsigned>(len_);
584 return (output.str());
585}
586
587vector<uint8_t>
589 vector<uint8_t> output;
590 // type(1) + length(1) + reserved(1) + prefix_len(1) + prefix(16)
591 output.resize(20);
592 output[0] = getType();
593 output[1] = 20;
594 output[2] = 0;
595 output[3] = len_;
596 vector<uint8_t> binary = value_.toBytes();
597 memmove(&output[4], &binary[0], output.size() - 4);
598 return (output);
599}
600
605 if (def) {
606 output->set("name", Element::create(def->name_));
607 }
608 output->set("type", Element::create(static_cast<int>(getType())));
609 ostringstream val;
610 val << value_.toText() << "/" << static_cast<unsigned>(len_);
611 output->set("data", Element::create(val.str()));
612 return (output);
613}
614
615void
617 if (!attr) {
618 return;
619 }
620 static_cast<void>(container_.push_back(attr));
621}
622
623bool
624Attributes::del(const uint8_t type) {
625 auto& idx = container_.get<1>();
626 auto it = idx.find(type);
627 if (it != idx.end()) {
628 idx.erase(it);
629 return (true);
630 }
631 return (false);
632}
633
634void
636 for (auto const& it : other) {
637 add(it);
638 }
639}
640
641size_t
642Attributes::count(const uint8_t type) const {
643 auto const& idx = container_.get<1>();
644 return (idx.count(type));
645}
646
648Attributes::get(const uint8_t type) const {
649 auto const& idx = container_.get<1>();
650 auto it = idx.find(type);
651 if (it != idx.end()) {
652 return (*it);
653 } else {
654 return(ConstAttributePtr());
655 }
656}
657
658string
659Attributes::toText(size_t indent) const {
660 ostringstream output;
661 bool first = true;
662 for (auto const& it : *this) {
663 if (!first) {
664 output << ",\n";
665 } else {
666 first = false;
667 }
668 output << it->toText(indent);
669 }
670 return (output.str());
671}
672
676 for (auto const& it : *this) {
677 output->add(it->toElement());
678 }
679 return (output);
680}
681
684 Attributes attrs;
685 if (!attr_list || (attr_list->getType() != Element::list)) {
686 return (attrs);
687 }
688 for (auto const& entry : attr_list->listValue()) {
689 if (!entry || (entry->getType() != Element::map)) {
690 continue;
691 }
692 ConstElementPtr attr_type = entry->get("type");
693 if (!attr_type || (attr_type->getType() != Element::integer)) {
694 continue;
695 }
696 AttrDefPtr def = AttrDefs::instance().getByType(attr_type->intValue());
697 if (!def) {
698 continue;
699 }
700 if (def->value_type_ == PW_TYPE_STRING) {
701 ConstElementPtr raw = entry->get("raw");
702 if (raw && (raw->getType() == Element::string) &&
703 (!raw->stringValue().empty())) {
704 try {
705 vector<uint8_t> binary;
706 encode::decodeHex(raw->stringValue(), binary);
707 AttributePtr attr = Attribute::fromBytes(def, binary);
708 attrs.add(attr);
709 continue;
710 } catch (...) {
711 continue;
712 }
713 }
714 }
715 ConstElementPtr data = entry->get("data");
716 if (data && (data->getType() == Element::string) &&
717 (!data->stringValue().empty())) {
718 AttributePtr attr = Attribute::fromText(def, data->stringValue());
719 attrs.add(attr);
720 continue;
721 }
722 }
723 return (attrs);
724}
725
726} // end of namespace isc::radius
727} // end of namespace isc
if(!(yy_init))
static ElementPtr create(const Position &pos=ZERO_POSITION())
Definition data.cc:249
@ map
Definition data.h:147
@ integer
Definition data.h:140
@ list
Definition data.h:146
@ string
Definition data.h:144
static ElementPtr createMap(const Position &pos=ZERO_POSITION())
Creates an empty MapElement type ElementPtr.
Definition data.cc:304
static ElementPtr createList(const Position &pos=ZERO_POSITION())
Creates an empty ListElement type ElementPtr.
Definition data.cc:299
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 an object can not be found.
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:36
static AttrDefs & instance()
Returns a single instance.
AttrDefPtr getByName(const std::string &name) const
Get attribute definition by name.
std::string getName(const uint8_t type) const
Get attribute name.
AttrDefPtr getByType(const uint8_t type) const
Get attribute definition by type.
IntCstDefPtr getByValue(const uint8_t type, const uint32_t value) const
Get integer constant definition by attribute type and value.
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.
static AttributePtr fromBytes(const std::vector< uint8_t > &bytes)
From bytes (wire format).
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.
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 std::string &repr)
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.
Collection of attributes.
void add(const ConstAttributePtr &attr)
Adds instance of the attribute to the collection.
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.
bool del(const uint8_t type)
Deletes an attribute from the collection.
static Attributes fromElement(const data::ConstElementPtr &attr_list)
Parse collection.
#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:29
boost::shared_ptr< Element > ElementPtr
Definition data.h:28
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
string trim(const string &input)
Trim leading and trailing spaces.
Definition str.cc:32
Defines the logger used by the top-level component of kea-lfc.