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 <limits>
37#include <sstream>
38#include <string>
39#include <vector>
40#include <map>
41
42namespace join
43{
45 using ByteList = std::vector<uint8_t>;
46
48 using WordList = std::vector<uint16_t>;
49
51 using IpList = std::vector<IpAddress>;
52
56
61 {
62 public:
66 enum Code : uint8_t
67 {
68 Pad = 0,
71 Router = 3,
141 End = 255,
142 };
143
160
164 struct Info
165 {
166 uint8_t code;
167 const char* name;
169 uint32_t min;
170 uint32_t max;
171 uint32_t mask;
172 };
173
175 using Options = std::map<uint8_t, DhcpOptionValue>;
176
178 using const_iterator = Options::const_iterator;
179
183 DhcpOption () = default;
184
191 : _options (first, last)
192 {
193 }
194
199 DhcpOption (const DhcpOption& other) = default;
200
206 DhcpOption& operator= (const DhcpOption& other) = default;
207
212 DhcpOption (DhcpOption&& other) = default;
213
219 DhcpOption& operator= (DhcpOption&& other) = default;
220
224 ~DhcpOption () = default;
225
232 const DhcpOptionValue& at (uint8_t code) const
233 {
234 return _options.at (code);
235 }
236
242 template <typename T>
243 const T* getIf (uint8_t code) const
244 {
245 auto it = _options.find (code);
246 return (it == _options.end ()) ? nullptr : it->second.getIf<T> ();
247 }
248
254 const_iterator find (uint8_t code) const
255 {
256 return _options.find (code);
257 }
258
264 bool contains (uint8_t code) const
265 {
266 return (find (code) != end ());
267 }
268
274 {
275 return _options.begin ();
276 }
277
283 {
284 return _options.cbegin ();
285 }
286
292 {
293 return _options.end ();
294 }
295
301 {
302 return _options.cend ();
303 }
304
309 bool empty () const
310 {
311 return _options.empty ();
312 }
313
318 size_t size () const
319 {
320 return _options.size ();
321 }
322
328 size_t erase (uint8_t code)
329 {
330 return _options.erase (code);
331 }
332
336 void clear ()
337 {
338 _options.clear ();
339 }
340
347 template <typename T>
348 bool insert (uint8_t code, T&& value)
349 {
350 DhcpOptionValue converted;
351
352 if (!convert (code, std::forward<T> (value), converted))
353 {
354 return false;
355 }
356
357 if (!_options.emplace (code, std::move (converted)).second)
358 {
359 lastError = make_error_code (Errc::InUse);
360 return false;
361 }
362
363 return true;
364 }
365
372 {
373 _options.insert (first, last);
374 }
375
380 void swap (DhcpOption& other)
381 {
382 _options.swap (other._options);
383 }
384
389 std::string dump () const
390 {
391 std::stringstream stream;
392
393 for (auto const& option : _options)
394 {
395 stream << codeName (option.first) << " (" << int (option.first) << "): ";
396 write (stream, option.first, option.second);
397 stream << "\n";
398 }
399
400 return stream.str ();
401 }
402
409 template <typename T>
410 static bool isValid (uint8_t code, T&& value)
411 {
412 DhcpOptionValue converted;
413 return convert (code, std::forward<T> (value), converted);
414 }
415
421 static const Info* describe (uint8_t code) noexcept;
422
423 protected:
429 static const char* codeName (uint8_t code) noexcept;
430
437 static void write (std::ostream& stream, uint8_t code, const DhcpOptionValue& value);
438
445 static bool accepts (const Info& info, uint32_t value) noexcept
446 {
447 if (info.mask)
448 {
449 return (value < 32) && ((info.mask >> value) & 1u);
450 }
451
452 if (info.max)
453 {
454 return (value >= info.min) && (value <= info.max);
455 }
456
457 return true;
458 }
459
465 template <typename Target, typename Source>
466 static typename std::enable_if<std::is_signed<Source>::value, bool>::type fits (Source value) noexcept
467 {
468 if (value < 0)
469 {
470 return std::is_signed<Target>::value &&
471 static_cast<int64_t> (value) >= static_cast<int64_t> (std::numeric_limits<Target>::min ());
472 }
473
474 return static_cast<uint64_t> (value) <= static_cast<uint64_t> (std::numeric_limits<Target>::max ());
475 }
476
482 template <typename Target, typename Source>
483 static typename std::enable_if<!std::is_signed<Source>::value, bool>::type fits (Source value) noexcept
484 {
485 return static_cast<uint64_t> (value) <= static_cast<uint64_t> (std::numeric_limits<Target>::max ());
486 }
487
495 template <typename Target, typename Source>
496 static bool store (const Info& info, Source value, DhcpOptionValue& out)
497 {
498 if (!fits<Target> (value) || !accepts (info, static_cast<uint32_t> (value)))
499 {
501 return false;
502 }
503
504 out = static_cast<Target> (value);
505
506 return true;
507 }
508
513 static bool invalid () noexcept
514 {
516 return false;
517 }
518
526 template <typename T>
527 static typename std::enable_if<std::is_integral<typename std::decay<T>::type>::value, bool>::type convert (
528 uint8_t code, T value, DhcpOptionValue& out)
529 {
530 const Info* info = describe (code);
531 if (info == nullptr)
532 {
533 return invalid ();
534 }
535
536 switch (info->type)
537 {
538 case Byte:
539 return store<uint8_t> (*info, value, out);
540
541 case Word:
542 return store<uint16_t> (*info, value, out);
543
544 case Long:
545 return store<uint32_t> (*info, value, out);
546
547 case SLong:
548 return store<int32_t> (*info, value, out);
549
550 default:
551 break;
552 }
553
554 return invalid ();
555 }
556
564 static bool convert (uint8_t code, const std::string& value, DhcpOptionValue& out);
565
573 static bool convert (uint8_t code, const char* value, DhcpOptionValue& out)
574 {
575 return convert (code, std::string (value), out);
576 }
577
585 static bool convert (uint8_t code, const IpAddress& value, DhcpOptionValue& out)
586 {
587 const Info* info = describe (code);
588 if ((info == nullptr) || (info->type != Ip) || (value.family () != AF_INET))
589 {
590 return invalid ();
591 }
592
593 out = value;
594
595 return true;
596 }
597
605 static bool convert (uint8_t code, const MacAddress& value, DhcpOptionValue& out)
606 {
607 const Info* info = describe (code);
608 if ((info == nullptr) || (info->type != Mac))
609 {
610 return invalid ();
611 }
612
613 out = value;
614
615 return true;
616 }
617
625 static bool convert (uint8_t code, const ByteList& value, DhcpOptionValue& out);
626
634 static bool convert (uint8_t code, const WordList& value, DhcpOptionValue& out);
635
643 static bool convert (uint8_t code, const IpList& value, DhcpOptionValue& out);
644
647
649 friend bool operator== (const DhcpOption& lhs, const DhcpOption& rhs);
650
652 friend bool operator!= (const DhcpOption& lhs, const DhcpOption& rhs);
653
655 friend bool operator< (const DhcpOption& lhs, const DhcpOption& rhs);
656
658 friend bool operator> (const DhcpOption& lhs, const DhcpOption& rhs);
659
661 friend bool operator<= (const DhcpOption& lhs, const DhcpOption& rhs);
662
664 friend bool operator>= (const DhcpOption& lhs, const DhcpOption& rhs);
665 };
666
673 inline bool operator== (const DhcpOption& lhs, const DhcpOption& rhs)
674 {
675 return lhs._options == rhs._options;
676 }
677
684 inline bool operator!= (const DhcpOption& lhs, const DhcpOption& rhs)
685 {
686 return lhs._options != rhs._options;
687 }
688
695 inline bool operator< (const DhcpOption& lhs, const DhcpOption& rhs)
696 {
697 return lhs._options < rhs._options;
698 }
699
706 inline bool operator> (const DhcpOption& lhs, const DhcpOption& rhs)
707 {
708 return lhs._options > rhs._options;
709 }
710
717 inline bool operator<= (const DhcpOption& lhs, const DhcpOption& rhs)
718 {
719 return lhs._options <= rhs._options;
720 }
721
728 inline bool operator>= (const DhcpOption& lhs, const DhcpOption& rhs)
729 {
730 return lhs._options >= rhs._options;
731 }
732
739 inline std::ostream& operator<< (std::ostream& out, const DhcpOption& options)
740 {
741 out << options.dump ();
742 return out;
743 }
744}
745
746#endif
DHCP option list.
Definition dhcp_option.hpp:61
static bool isValid(uint8_t code, T &&value)
check that a value can be carried by the given option.
Definition dhcp_option.hpp:410
size_t size() const
get the number of options in the list.
Definition dhcp_option.hpp:318
Code
option codes.
Definition dhcp_option.hpp:67
@ Router
Definition dhcp_option.hpp:71
@ Message
Definition dhcp_option.hpp:124
@ BootFileName
Definition dhcp_option.hpp:131
@ DefaultWwwServer
Definition dhcp_option.hpp:136
@ ServerIdentifier
Definition dhcp_option.hpp:122
@ TcpDefaultTtl
Definition dhcp_option.hpp:105
@ NetbiosDatagramDistributionServer
Definition dhcp_option.hpp:113
@ TimeOffset
Definition dhcp_option.hpp:70
@ XWindowFontServer
Definition dhcp_option.hpp:116
@ IpForwarding
Definition dhcp_option.hpp:87
@ RebindingTimeValue
Definition dhcp_option.hpp:127
@ BroadcastAddress
Definition dhcp_option.hpp:96
@ NetworkInformationServer
Definition dhcp_option.hpp:109
@ StreetTalkDirectoryAssistanceServer
Definition dhcp_option.hpp:140
@ MeritDumpFile
Definition dhcp_option.hpp:82
@ XWindowDisplayManager
Definition dhcp_option.hpp:117
@ DomainNameServer
Definition dhcp_option.hpp:74
@ ExtensionsPath
Definition dhcp_option.hpp:86
@ PerformRouterDiscovery
Definition dhcp_option.hpp:99
@ IpAddressLeaseTime
Definition dhcp_option.hpp:119
@ EthernetEncapsulation
Definition dhcp_option.hpp:104
@ DefaultIrcServer
Definition dhcp_option.hpp:138
@ MaskSupplier
Definition dhcp_option.hpp:98
@ NisDomain
Definition dhcp_option.hpp:108
@ RenewalTimeValue
Definition dhcp_option.hpp:126
@ StreetTalkServer
Definition dhcp_option.hpp:139
@ NameServer
Definition dhcp_option.hpp:73
@ PolicyFilter
Definition dhcp_option.hpp:89
@ OptionOverload
Definition dhcp_option.hpp:120
@ SmtpServer
Definition dhcp_option.hpp:133
@ ParameterRequestList
Definition dhcp_option.hpp:123
@ TrailerEncapsulation
Definition dhcp_option.hpp:102
@ LogServer
Definition dhcp_option.hpp:75
@ TcpKeepaliveGarbage
Definition dhcp_option.hpp:107
@ RouterSolicitationAddress
Definition dhcp_option.hpp:100
@ Pad
Definition dhcp_option.hpp:68
@ TftpServerName
Definition dhcp_option.hpp:130
@ RootPath
Definition dhcp_option.hpp:85
@ DefaultFingerServer
Definition dhcp_option.hpp:137
@ NetbiosScope
Definition dhcp_option.hpp:115
@ VendorClassIdentifier
Definition dhcp_option.hpp:128
@ NntpServer
Definition dhcp_option.hpp:135
@ DomainName
Definition dhcp_option.hpp:83
@ SubnetMask
Definition dhcp_option.hpp:69
@ DefaultIpTimeToLive
Definition dhcp_option.hpp:91
@ ImpressServer
Definition dhcp_option.hpp:78
@ LprServer
Definition dhcp_option.hpp:77
@ ClientIdentifier
Definition dhcp_option.hpp:129
@ TimeServer
Definition dhcp_option.hpp:72
@ SwapServer
Definition dhcp_option.hpp:84
@ PathMtuPlateauTable
Definition dhcp_option.hpp:93
@ NetbiosNameServer
Definition dhcp_option.hpp:112
@ ResourceLocationServer
Definition dhcp_option.hpp:79
@ StaticRoute
Definition dhcp_option.hpp:101
@ AllSubnetsAreLocal
Definition dhcp_option.hpp:95
@ Pop3Server
Definition dhcp_option.hpp:134
@ MaximumDhcpMessageSize
Definition dhcp_option.hpp:125
@ End
Definition dhcp_option.hpp:141
@ MaximumDatagramReassemblySize
Definition dhcp_option.hpp:90
@ RequestedIpAddress
Definition dhcp_option.hpp:118
@ VendorSpecificInformation
Definition dhcp_option.hpp:111
@ DhcpMessageType
Definition dhcp_option.hpp:121
@ HostName
Definition dhcp_option.hpp:80
@ PathMtuAgingTimeout
Definition dhcp_option.hpp:92
@ InterfaceMtu
Definition dhcp_option.hpp:94
@ BootFileSize
Definition dhcp_option.hpp:81
@ NetbiosNodeType
Definition dhcp_option.hpp:114
@ ArpCacheTimeout
Definition dhcp_option.hpp:103
@ MobileIpHomeAgent
Definition dhcp_option.hpp:132
@ NonLocalSourceRouting
Definition dhcp_option.hpp:88
@ PerformMaskDiscovery
Definition dhcp_option.hpp:97
@ CookieServer
Definition dhcp_option.hpp:76
@ TcpKeepaliveInterval
Definition dhcp_option.hpp:106
@ NtpServer
Definition dhcp_option.hpp:110
const_iterator end() const
get an iterator to the element following the last element of the list.
Definition dhcp_option.hpp:291
friend bool operator!=(const DhcpOption &lhs, const DhcpOption &rhs)
friendship with not equal operator.
Definition dhcp_option.hpp:684
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:348
Options::const_iterator const_iterator
constant iterator from nested container.
Definition dhcp_option.hpp:178
friend bool operator<(const DhcpOption &lhs, const DhcpOption &rhs)
friendship with lower operator.
Definition dhcp_option.hpp:695
static bool store(const Info &info, Source value, DhcpOptionValue &out)
store an integer value as the given target type.
Definition dhcp_option.hpp:496
Type
type of the value an option carries on the wire.
Definition dhcp_option.hpp:148
@ Word
Definition dhcp_option.hpp:150
@ Ip
Definition dhcp_option.hpp:154
@ Mac
Definition dhcp_option.hpp:155
@ Text
Definition dhcp_option.hpp:153
@ Ips
Definition dhcp_option.hpp:158
@ SLong
Definition dhcp_option.hpp:152
@ Bytes
Definition dhcp_option.hpp:156
@ Long
Definition dhcp_option.hpp:151
@ Byte
Definition dhcp_option.hpp:149
@ Words
Definition dhcp_option.hpp:157
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:232
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:243
static std::enable_if<!std::is_signed< Source >::value, bool >::type fits(Source value) noexcept
check that an unsigned value can be represented by the target type.
Definition dhcp_option.hpp:483
const_iterator cend() const
get an iterator to the element following the last element of the list.
Definition dhcp_option.hpp:300
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:264
friend bool operator>=(const DhcpOption &lhs, const DhcpOption &rhs)
friendship with greater or equal operator.
Definition dhcp_option.hpp:728
DhcpOption(const DhcpOption &other)=default
create instance by copy.
const_iterator find(uint8_t code) const
find the element with the given code.
Definition dhcp_option.hpp:254
std::map< uint8_t, DhcpOptionValue > Options
option list.
Definition dhcp_option.hpp:175
void swap(DhcpOption &other)
exchange the contents of the list with those of other.
Definition dhcp_option.hpp:380
friend bool operator>(const DhcpOption &lhs, const DhcpOption &rhs)
friendship with greater operator.
Definition dhcp_option.hpp:706
void clear()
remove all elements from the list.
Definition dhcp_option.hpp:336
bool empty() const
check if the list has no element.
Definition dhcp_option.hpp:309
static bool invalid() noexcept
report an invalid option value.
Definition dhcp_option.hpp:513
DhcpOption(const_iterator first, const_iterator last)
create the DhcpOption instance with the elements from range.
Definition dhcp_option.hpp:190
std::string dump() const
dump the options in string format.
Definition dhcp_option.hpp:389
size_t erase(uint8_t code)
remove the element identified by code.
Definition dhcp_option.hpp:328
static bool convert(uint8_t code, const MacAddress &value, DhcpOptionValue &out)
store a hardware address in the given option.
Definition dhcp_option.hpp:605
friend bool operator<=(const DhcpOption &lhs, const DhcpOption &rhs)
friendship with lower or equal operator.
Definition dhcp_option.hpp:717
void insert(const_iterator first, const_iterator last)
insert elements from range.
Definition dhcp_option.hpp:371
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:573
~DhcpOption()=default
destroy the DhcpOption instance.
DhcpOption()=default
create the DhcpOption instance.
Options _options
options.
Definition dhcp_option.hpp:646
static bool convert(uint8_t code, const IpAddress &value, DhcpOptionValue &out)
store an IP address in the given option.
Definition dhcp_option.hpp:585
const_iterator begin() const
get an iterator to the first element of the list.
Definition dhcp_option.hpp:273
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:282
static std::enable_if< std::is_signed< Source >::value, bool >::type fits(Source value) noexcept
check that a signed value can be represented by the target type.
Definition dhcp_option.hpp:466
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:445
static std::enable_if< std::is_integral< typenamestd::decay< T >::type >::value, bool >::type convert(uint8_t code, T value, DhcpOptionValue &out)
convert an integer to the type the given option carries.
Definition dhcp_option.hpp:527
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:673
IPv6, IPv4 address class.
Definition ip_address.hpp:51
int family() const
get address family.
Definition ip_address.cpp:1250
MAC address class.
Definition mac_address.hpp:46
variant class.
Definition variant.hpp:352
Definition acceptor.hpp:32
bool operator<=(const BasicLinkLayerEndpoint< Protocol > &a, const BasicLinkLayerEndpoint< Protocol > &b) noexcept
compare if endpoint is lower or equal.
Definition endpoint.hpp:234
bool operator==(const BasicLinkLayerEndpoint< Protocol > &a, const BasicLinkLayerEndpoint< Protocol > &b) noexcept
compare if endpoints are equal.
Definition endpoint.hpp:186
std::vector< IpAddress > IpList
list of IP addresses.
Definition dhcp_option.hpp:51
std::vector< uint16_t > WordList
list of 16 bits words.
Definition dhcp_option.hpp:48
bool operator!=(const BasicLinkLayerEndpoint< Protocol > &a, const BasicLinkLayerEndpoint< Protocol > &b) noexcept
compare if endpoints are not equal.
Definition endpoint.hpp:198
bool operator>=(const BasicLinkLayerEndpoint< Protocol > &a, const BasicLinkLayerEndpoint< Protocol > &b) noexcept
compare if endpoint is greater or equal.
Definition endpoint.hpp:246
std::ostream & operator<<(std::ostream &os, const BasicLinkLayerEndpoint< Protocol > &endpoint)
push endpoint representation into a stream.
Definition endpoint.hpp:258
bool operator<(const BasicDatagramSocket< Protocol > &a, const BasicDatagramSocket< Protocol > &b) noexcept
compare if socket handle is inferior.
Definition datagram_socket.hpp:394
std::error_code make_error_code(join::Errc code) noexcept
Create an std::error_code object.
Definition error.cpp:195
bool operator>(const BasicLinkLayerEndpoint< Protocol > &a, const BasicLinkLayerEndpoint< Protocol > &b) noexcept
compare if endpoint is greater.
Definition endpoint.hpp:222
std::vector< uint8_t > ByteList
list of bytes.
Definition dhcp_option.hpp:45
description of an option.
Definition dhcp_option.hpp:165
uint32_t min
Definition dhcp_option.hpp:169
Type type
Definition dhcp_option.hpp:168
uint32_t mask
Definition dhcp_option.hpp:171
const char * name
Definition dhcp_option.hpp:167
uint32_t max
Definition dhcp_option.hpp:170
uint8_t code
Definition dhcp_option.hpp:166