join 1.0
lightweight network framework library
Loading...
Searching...
No Matches
dhcp_option.hpp
Go to the documentation of this file.
1
25#ifndef JOIN_FABRIC_DHCP_OPTION_HPP
26#define JOIN_FABRIC_DHCP_OPTION_HPP
27
28// libjoin.
29#include <join/mac_address.hpp>
30#include <join/ip_address.hpp>
31#include <join/variant.hpp>
32#include <join/error.hpp>
33
34// C++.
35#include <type_traits>
36#include <concepts>
37#include <sstream>
38#include <utility>
39#include <compare>
40#include <limits>
41#include <string>
42#include <vector>
43#include <map>
44
45namespace join
46{
48 using ByteList = std::vector<uint8_t>;
49
51 using WordList = std::vector<uint16_t>;
52
54 using IpList = std::vector<IpAddress>;
55
59
64 {
65 public:
69 enum Code : uint8_t
70 {
71 Pad = 0,
74 Router = 3,
144 End = 255,
145 };
146
163
167 struct Info
168 {
169 uint8_t code;
170 const char* name;
172 uint32_t min;
173 uint32_t max;
174 uint32_t mask;
175 };
176
178 using Options = std::map<uint8_t, DhcpOptionValue>;
179
181 using const_iterator = Options::const_iterator;
182
186 DhcpOption () = default;
187
194 : _options (first, last)
195 {
196 }
197
202 DhcpOption (const DhcpOption& other) = default;
203
209 DhcpOption& operator= (const DhcpOption& other) = default;
210
215 DhcpOption (DhcpOption&& other) = default;
216
222 DhcpOption& operator= (DhcpOption&& other) = default;
223
227 ~DhcpOption () = default;
228
235 const DhcpOptionValue& at (uint8_t code) const
236 {
237 return _options.at (code);
238 }
239
245 template <typename T>
246 const T* getIf (uint8_t code) const
247 {
248 auto it = _options.find (code);
249 return (it == _options.end ()) ? nullptr : it->second.getIf<T> ();
250 }
251
257 const_iterator find (uint8_t code) const
258 {
259 return _options.find (code);
260 }
261
267 bool contains (uint8_t code) const
268 {
269 return (find (code) != end ());
270 }
271
277 {
278 return _options.begin ();
279 }
280
286 {
287 return _options.cbegin ();
288 }
289
295 {
296 return _options.end ();
297 }
298
304 {
305 return _options.cend ();
306 }
307
312 bool empty () const
313 {
314 return _options.empty ();
315 }
316
321 size_t size () const
322 {
323 return _options.size ();
324 }
325
331 size_t erase (uint8_t code)
332 {
333 return _options.erase (code);
334 }
335
339 void clear ()
340 {
341 _options.clear ();
342 }
343
350 template <typename T>
351 bool insert (uint8_t code, T&& value)
352 {
353 DhcpOptionValue converted;
354
355 if (!convert (code, std::forward<T> (value), converted))
356 {
357 return false;
358 }
359
360 if (!_options.emplace (code, std::move (converted)).second)
361 {
362 lastError = make_error_code (Errc::InUse);
363 return false;
364 }
365
366 return true;
367 }
368
375 {
376 _options.insert (first, last);
377 }
378
383 void swap (DhcpOption& other)
384 {
385 _options.swap (other._options);
386 }
387
392 std::string dump () const
393 {
394 std::stringstream stream;
395
396 for (auto const& option : _options)
397 {
398 stream << codeName (option.first) << " (" << int (option.first) << "): ";
399 write (stream, option.first, option.second);
400 stream << "\n";
401 }
402
403 return stream.str ();
404 }
405
412 template <typename T>
413 static bool isValid (uint8_t code, T&& value)
414 {
415 DhcpOptionValue converted;
416 return convert (code, std::forward<T> (value), converted);
417 }
418
424 static const Info* describe (uint8_t code) noexcept;
425
426 protected:
432 static const char* codeName (uint8_t code) noexcept;
433
440 static void write (std::ostream& stream, uint8_t code, const DhcpOptionValue& value);
441
448 static bool accepts (const Info& info, uint32_t value) noexcept
449 {
450 if (info.mask)
451 {
452 return (value < 32) && ((info.mask >> value) & 1u);
453 }
454
455 if (info.max)
456 {
457 return (value >= info.min) && (value <= info.max);
458 }
459
460 return true;
461 }
462
470 template <typename Target, typename Source>
471 static bool store (const Info& info, Source value, DhcpOptionValue& out)
472 {
473 if (!std::in_range<Target> (value) || !accepts (info, static_cast<uint32_t> (value)))
474 {
476 return false;
477 }
478
479 out = static_cast<Target> (value);
480
481 return true;
482 }
483
488 static bool invalid () noexcept
489 {
491 return false;
492 }
493
501 template <typename T>
502 static bool convert (uint8_t code, T value, DhcpOptionValue& out)
503 requires std::integral<T>
504 {
505 const Info* info = describe (code);
506 if (info == nullptr)
507 {
508 return invalid ();
509 }
510
511 switch (info->type)
512 {
513 case Byte:
514 return store<uint8_t> (*info, value, out);
515
516 case Word:
517 return store<uint16_t> (*info, value, out);
518
519 case Long:
520 return store<uint32_t> (*info, value, out);
521
522 case SLong:
523 return store<int32_t> (*info, value, out);
524
525 default:
526 break;
527 }
528
529 return invalid ();
530 }
531
539 static bool convert (uint8_t code, const std::string& value, DhcpOptionValue& out);
540
548 static bool convert (uint8_t code, const char* value, DhcpOptionValue& out)
549 {
550 return convert (code, std::string (value), out);
551 }
552
560 static bool convert (uint8_t code, const IpAddress& value, DhcpOptionValue& out)
561 {
562 const Info* info = describe (code);
563 if ((info == nullptr) || (info->type != Ip) || (value.family () != AF_INET))
564 {
565 return invalid ();
566 }
567
568 out = value;
569
570 return true;
571 }
572
580 static bool convert (uint8_t code, const MacAddress& value, DhcpOptionValue& out)
581 {
582 const Info* info = describe (code);
583 if ((info == nullptr) || (info->type != Mac))
584 {
585 return invalid ();
586 }
587
588 out = value;
589
590 return true;
591 }
592
600 static bool convert (uint8_t code, const ByteList& value, DhcpOptionValue& out);
601
609 static bool convert (uint8_t code, const WordList& value, DhcpOptionValue& out);
610
618 static bool convert (uint8_t code, const IpList& value, DhcpOptionValue& out);
619
622
624 friend bool operator== (const DhcpOption& lhs, const DhcpOption& rhs);
625
627 friend std::weak_ordering operator<=> (const DhcpOption& lhs, const DhcpOption& rhs);
628 };
629
636 inline bool operator== (const DhcpOption& lhs, const DhcpOption& rhs)
637 {
638 return lhs._options == rhs._options;
639 }
640
647 inline std::weak_ordering operator<=> (const DhcpOption& lhs, const DhcpOption& rhs)
648 {
649 return lhs._options <=> rhs._options;
650 }
651
658 inline std::ostream& operator<< (std::ostream& out, const DhcpOption& options)
659 {
660 out << options.dump ();
661 return out;
662 }
663}
664
665#endif
DHCP option list.
Definition dhcp_option.hpp:64
static bool isValid(uint8_t code, T &&value)
check that a value can be carried by the given option.
Definition dhcp_option.hpp:413
size_t size() const
get the number of options in the list.
Definition dhcp_option.hpp:321
Code
option codes.
Definition dhcp_option.hpp:70
@ Router
Definition dhcp_option.hpp:74
@ Message
Definition dhcp_option.hpp:127
@ BootFileName
Definition dhcp_option.hpp:134
@ DefaultWwwServer
Definition dhcp_option.hpp:139
@ ServerIdentifier
Definition dhcp_option.hpp:125
@ TcpDefaultTtl
Definition dhcp_option.hpp:108
@ NetbiosDatagramDistributionServer
Definition dhcp_option.hpp:116
@ TimeOffset
Definition dhcp_option.hpp:73
@ XWindowFontServer
Definition dhcp_option.hpp:119
@ IpForwarding
Definition dhcp_option.hpp:90
@ RebindingTimeValue
Definition dhcp_option.hpp:130
@ BroadcastAddress
Definition dhcp_option.hpp:99
@ NetworkInformationServer
Definition dhcp_option.hpp:112
@ StreetTalkDirectoryAssistanceServer
Definition dhcp_option.hpp:143
@ MeritDumpFile
Definition dhcp_option.hpp:85
@ XWindowDisplayManager
Definition dhcp_option.hpp:120
@ DomainNameServer
Definition dhcp_option.hpp:77
@ ExtensionsPath
Definition dhcp_option.hpp:89
@ PerformRouterDiscovery
Definition dhcp_option.hpp:102
@ IpAddressLeaseTime
Definition dhcp_option.hpp:122
@ EthernetEncapsulation
Definition dhcp_option.hpp:107
@ DefaultIrcServer
Definition dhcp_option.hpp:141
@ MaskSupplier
Definition dhcp_option.hpp:101
@ NisDomain
Definition dhcp_option.hpp:111
@ RenewalTimeValue
Definition dhcp_option.hpp:129
@ StreetTalkServer
Definition dhcp_option.hpp:142
@ NameServer
Definition dhcp_option.hpp:76
@ PolicyFilter
Definition dhcp_option.hpp:92
@ OptionOverload
Definition dhcp_option.hpp:123
@ SmtpServer
Definition dhcp_option.hpp:136
@ ParameterRequestList
Definition dhcp_option.hpp:126
@ TrailerEncapsulation
Definition dhcp_option.hpp:105
@ LogServer
Definition dhcp_option.hpp:78
@ TcpKeepaliveGarbage
Definition dhcp_option.hpp:110
@ RouterSolicitationAddress
Definition dhcp_option.hpp:103
@ Pad
Definition dhcp_option.hpp:71
@ TftpServerName
Definition dhcp_option.hpp:133
@ RootPath
Definition dhcp_option.hpp:88
@ DefaultFingerServer
Definition dhcp_option.hpp:140
@ NetbiosScope
Definition dhcp_option.hpp:118
@ VendorClassIdentifier
Definition dhcp_option.hpp:131
@ NntpServer
Definition dhcp_option.hpp:138
@ DomainName
Definition dhcp_option.hpp:86
@ SubnetMask
Definition dhcp_option.hpp:72
@ DefaultIpTimeToLive
Definition dhcp_option.hpp:94
@ ImpressServer
Definition dhcp_option.hpp:81
@ LprServer
Definition dhcp_option.hpp:80
@ ClientIdentifier
Definition dhcp_option.hpp:132
@ TimeServer
Definition dhcp_option.hpp:75
@ SwapServer
Definition dhcp_option.hpp:87
@ PathMtuPlateauTable
Definition dhcp_option.hpp:96
@ NetbiosNameServer
Definition dhcp_option.hpp:115
@ ResourceLocationServer
Definition dhcp_option.hpp:82
@ StaticRoute
Definition dhcp_option.hpp:104
@ AllSubnetsAreLocal
Definition dhcp_option.hpp:98
@ Pop3Server
Definition dhcp_option.hpp:137
@ MaximumDhcpMessageSize
Definition dhcp_option.hpp:128
@ End
Definition dhcp_option.hpp:144
@ MaximumDatagramReassemblySize
Definition dhcp_option.hpp:93
@ RequestedIpAddress
Definition dhcp_option.hpp:121
@ VendorSpecificInformation
Definition dhcp_option.hpp:114
@ DhcpMessageType
Definition dhcp_option.hpp:124
@ HostName
Definition dhcp_option.hpp:83
@ PathMtuAgingTimeout
Definition dhcp_option.hpp:95
@ InterfaceMtu
Definition dhcp_option.hpp:97
@ BootFileSize
Definition dhcp_option.hpp:84
@ NetbiosNodeType
Definition dhcp_option.hpp:117
@ ArpCacheTimeout
Definition dhcp_option.hpp:106
@ MobileIpHomeAgent
Definition dhcp_option.hpp:135
@ NonLocalSourceRouting
Definition dhcp_option.hpp:91
@ PerformMaskDiscovery
Definition dhcp_option.hpp:100
@ CookieServer
Definition dhcp_option.hpp:79
@ TcpKeepaliveInterval
Definition dhcp_option.hpp:109
@ NtpServer
Definition dhcp_option.hpp:113
const_iterator end() const
get an iterator to the element following the last element of the list.
Definition dhcp_option.hpp:294
bool insert(uint8_t code, T &&value)
add an option to the list, converting the value to the type the option carries.
Definition dhcp_option.hpp:351
Options::const_iterator const_iterator
constant iterator from nested container.
Definition dhcp_option.hpp:181
static bool store(const Info &info, Source value, DhcpOptionValue &out)
store an integer value as the given target type.
Definition dhcp_option.hpp:471
Type
type of the value an option carries on the wire.
Definition dhcp_option.hpp:151
@ Word
Definition dhcp_option.hpp:153
@ Ip
Definition dhcp_option.hpp:157
@ Mac
Definition dhcp_option.hpp:158
@ Text
Definition dhcp_option.hpp:156
@ Ips
Definition dhcp_option.hpp:161
@ SLong
Definition dhcp_option.hpp:155
@ Bytes
Definition dhcp_option.hpp:159
@ Long
Definition dhcp_option.hpp:154
@ Byte
Definition dhcp_option.hpp:152
@ Words
Definition dhcp_option.hpp:160
DhcpOption(DhcpOption &&other)=default
create instance by move.
const DhcpOptionValue & at(uint8_t code) const
get the value identified by code, with range verification.
Definition dhcp_option.hpp:235
const T * getIf(uint8_t code) const
get the value identified by code if it is present and holds the requested type.
Definition dhcp_option.hpp:246
const_iterator cend() const
get an iterator to the element following the last element of the list.
Definition dhcp_option.hpp:303
static const char * codeName(uint8_t code) noexcept
get the name of the given option.
Definition dhcp_option.cpp:127
bool contains(uint8_t code) const
check if there is an element identified by code in the list.
Definition dhcp_option.hpp:267
DhcpOption(const DhcpOption &other)=default
create instance by copy.
friend std::weak_ordering operator<=>(const DhcpOption &lhs, const DhcpOption &rhs)
friendship with three-way comparison operator.
Definition dhcp_option.hpp:647
const_iterator find(uint8_t code) const
find the element with the given code.
Definition dhcp_option.hpp:257
std::map< uint8_t, DhcpOptionValue > Options
option list.
Definition dhcp_option.hpp:178
void swap(DhcpOption &other)
exchange the contents of the list with those of other.
Definition dhcp_option.hpp:383
void clear()
remove all elements from the list.
Definition dhcp_option.hpp:339
bool empty() const
check if the list has no element.
Definition dhcp_option.hpp:312
static bool invalid() noexcept
report an invalid option value.
Definition dhcp_option.hpp:488
DhcpOption(const_iterator first, const_iterator last)
create the DhcpOption instance with the elements from range.
Definition dhcp_option.hpp:193
std::string dump() const
dump the options in string format.
Definition dhcp_option.hpp:392
size_t erase(uint8_t code)
remove the element identified by code.
Definition dhcp_option.hpp:331
static bool convert(uint8_t code, const MacAddress &value, DhcpOptionValue &out)
store a hardware address in the given option.
Definition dhcp_option.hpp:580
void insert(const_iterator first, const_iterator last)
insert elements from range.
Definition dhcp_option.hpp:374
static bool convert(uint8_t code, T value, DhcpOptionValue &out)
convert an integer to the type the given option carries.
Definition dhcp_option.hpp:502
static bool convert(uint8_t code, const char *value, DhcpOptionValue &out)
convert a string to the type the given option carries.
Definition dhcp_option.hpp:548
~DhcpOption()=default
destroy the DhcpOption instance.
DhcpOption()=default
create the DhcpOption instance.
Options _options
options.
Definition dhcp_option.hpp:621
static bool convert(uint8_t code, const IpAddress &value, DhcpOptionValue &out)
store an IP address in the given option.
Definition dhcp_option.hpp:560
const_iterator begin() const
get an iterator to the first element of the list.
Definition dhcp_option.hpp:276
static void write(std::ostream &stream, uint8_t code, const DhcpOptionValue &value)
write an option value in string format.
Definition dhcp_option.cpp:137
const_iterator cbegin() const
get an iterator to the first element of the list.
Definition dhcp_option.hpp:285
static bool accepts(const Info &info, uint32_t value) noexcept
check that a value satisfies the constraints of the given option.
Definition dhcp_option.hpp:448
static const Info * describe(uint8_t code) noexcept
get the description of the given option.
Definition dhcp_option.cpp:41
DhcpOption & operator=(const DhcpOption &other)=default
assign instance by copy.
friend bool operator==(const DhcpOption &lhs, const DhcpOption &rhs)
friendship with equal operator.
Definition dhcp_option.hpp:636
IPv6, IPv4 address class.
Definition ip_address.hpp:52
int family() const
get address family.
Definition ip_address.cpp:1250
MAC address class.
Definition mac_address.hpp:47
variant class.
Definition variant.hpp:225
Definition acceptor.hpp:32
bool operator==(const BasicLinkLayerEndpoint< Protocol > &a, const BasicLinkLayerEndpoint< Protocol > &b) noexcept
compare if endpoints are equal.
Definition endpoint.hpp:196
std::vector< IpAddress > IpList
list of IP addresses.
Definition dhcp_option.hpp:54
std::vector< uint16_t > WordList
list of 16 bits words.
Definition dhcp_option.hpp:51
std::ostream & operator<<(std::ostream &os, const BasicLinkLayerEndpoint< Protocol > &endpoint)
push endpoint representation into a stream.
Definition endpoint.hpp:221
std::error_code make_error_code(join::Errc code) noexcept
Create an std::error_code object.
Definition error.cpp:195
std::strong_ordering operator<=>(const BasicLinkLayerEndpoint< Protocol > &a, const BasicLinkLayerEndpoint< Protocol > &b) noexcept
three-way compare endpoints.
Definition endpoint.hpp:208
std::vector< uint8_t > ByteList
list of bytes.
Definition dhcp_option.hpp:48
description of an option.
Definition dhcp_option.hpp:168
uint32_t min
Definition dhcp_option.hpp:172
Type type
Definition dhcp_option.hpp:171
uint32_t mask
Definition dhcp_option.hpp:174
const char * name
Definition dhcp_option.hpp:170
uint32_t max
Definition dhcp_option.hpp:173
uint8_t code
Definition dhcp_option.hpp:169