EtcPal  HEAD (unstable)
ETC Platform Abstraction Layer (EtcPal)
View other versions:
inet.h
Go to the documentation of this file.
1 /******************************************************************************
2  * Copyright 2022 ETC Inc.
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  * http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  *******************************************************************************
16  * This file is a part of EtcPal. For more information, go to:
17  * https://github.com/ETCLabs/EtcPal
18  ******************************************************************************/
19 
22 
23 #ifndef ETCPAL_CPP_INET_H_
24 #define ETCPAL_CPP_INET_H_
25 
26 #include <algorithm>
27 #include <array>
28 #include <cstring>
29 #include <iterator>
30 #include <string>
31 #include "etcpal/inet.h"
32 #include "etcpal/cpp/common.h"
33 #include "etcpal/cpp/hash.h"
34 #include "etcpal/cpp/opaque_id.h"
35 
36 namespace etcpal
37 {
44 
47 enum class IpAddrType
48 {
49  kInvalid = kEtcPalIpTypeInvalid,
50  kV4 = kEtcPalIpTypeV4,
51  kV6 = kEtcPalIpTypeV6
52 };
53 
58 class IpAddr
59 {
60 public:
61  ETCPAL_CONSTEXPR_14 IpAddr() noexcept;
62  // Note: this constructor is not explicit by design, to allow implicit conversions e.g.
63  // etcpal::IpAddr ip = etcpal_c_function_that_returns_ip();
64  constexpr IpAddr(const EtcPalIpAddr& c_ip) noexcept;
65  IpAddr& operator=(const EtcPalIpAddr& c_ip) noexcept;
66 
67  ETCPAL_CONSTEXPR_14 IpAddr(uint32_t v4_data) noexcept;
68  explicit IpAddr(const uint8_t* v6_data) noexcept;
69  IpAddr(const uint8_t* v6_data, unsigned long scope_id) noexcept;
70 
71  constexpr const EtcPalIpAddr& get() const noexcept;
73  std::string ToString() const;
74  constexpr uint32_t v4_data() const noexcept;
75  constexpr const uint8_t* v6_data() const noexcept;
76  std::array<uint8_t, ETCPAL_IPV6_BYTES> ToV6Array() const;
77  constexpr unsigned long scope_id() const noexcept;
78 
79  constexpr bool IsValid() const noexcept;
80  constexpr IpAddrType type() const noexcept;
81  constexpr etcpal_iptype_t raw_type() const noexcept;
82  constexpr bool IsV4() const noexcept;
83  constexpr bool IsV6() const noexcept;
84  bool IsLinkLocal() const noexcept;
85  bool IsLoopback() const noexcept;
86  bool IsMulticast() const noexcept;
87  bool IsWildcard() const noexcept;
88  unsigned int MaskLength() const noexcept;
89 
90  void SetAddress(uint32_t v4_data) noexcept;
91  void SetAddress(const uint8_t* v6_data) noexcept;
92  void SetAddress(const uint8_t* v6_data, unsigned long scope_id) noexcept;
93 
94  static IpAddr FromString(const char* ip_str) noexcept;
95  static IpAddr FromString(const std::string& ip_str) noexcept;
96  static IpAddr WildcardV4() noexcept;
97  static IpAddr WildcardV6() noexcept;
98  static IpAddr Wildcard(IpAddrType type) noexcept;
99  static IpAddr NetmaskV4(unsigned int mask_length) noexcept;
100  static IpAddr NetmaskV6(unsigned int mask_length) noexcept;
101  static IpAddr Netmask(IpAddrType type, unsigned int mask_length) noexcept;
102 
103 private:
105 };
106 
109 {
110  ETCPAL_IP_SET_INVALID(&addr_);
111 }
112 
114 constexpr IpAddr::IpAddr(const EtcPalIpAddr& c_ip) noexcept : addr_(c_ip)
115 {
116 }
117 
119 inline IpAddr& IpAddr::operator=(const EtcPalIpAddr& c_ip) noexcept
120 {
121  addr_ = c_ip;
122  return *this;
123 }
124 
128 {
129  ETCPAL_IP_SET_V4_ADDRESS(&addr_, v4_data);
130 }
131 
134 inline IpAddr::IpAddr(const uint8_t* v6_data) noexcept
135 {
136  ETCPAL_IP_SET_V6_ADDRESS(&addr_, v6_data);
137 }
138 
145 inline IpAddr::IpAddr(const uint8_t* v6_data, unsigned long scope_id) noexcept
146 {
147  ETCPAL_IP_SET_V6_ADDRESS_WITH_SCOPE_ID(&addr_, v6_data, scope_id);
148 }
149 
151 constexpr const EtcPalIpAddr& IpAddr::get() const noexcept
152 {
153  return addr_;
154 }
155 
158 {
159  return addr_;
160 }
161 
165 inline std::string IpAddr::ToString() const
166 {
167  std::array<char, ETCPAL_IP_STRING_BYTES> str_buf; // NOLINT(cppcoreguidelines-pro-type-member-init)
168 
169  auto result = etcpal_ip_to_string(&addr_, str_buf.data());
170  if (result == kEtcPalErrOk)
171  return {str_buf.data()};
172  return {};
173 }
174 
180 constexpr uint32_t IpAddr::v4_data() const noexcept
181 {
182  return ETCPAL_IP_V4_ADDRESS(&addr_);
183 }
184 
189 constexpr const uint8_t* IpAddr::v6_data() const noexcept
190 {
191  return ETCPAL_IP_V6_ADDRESS(&addr_);
192 }
193 
198 inline std::array<uint8_t, ETCPAL_IPV6_BYTES> IpAddr::ToV6Array() const
199 {
200  // RVO should hopefully make this only a single copy
201  std::array<uint8_t, ETCPAL_IPV6_BYTES> arr; // NOLINT(cppcoreguidelines-pro-type-member-init)
202  std::memcpy(arr.data(), ETCPAL_IP_V6_ADDRESS(&addr_), ETCPAL_IPV6_BYTES);
203  return arr;
204 }
205 
215 constexpr unsigned long IpAddr::scope_id() const noexcept
216 {
217  return ETCPAL_IP_V6_SCOPE_ID(&addr_);
218 }
219 
221 constexpr bool IpAddr::IsValid() const noexcept
222 {
223  return !ETCPAL_IP_IS_INVALID(&addr_);
224 }
225 
227 constexpr IpAddrType IpAddr::type() const noexcept
228 {
229  return static_cast<IpAddrType>(addr_.type);
230 }
231 
233 constexpr etcpal_iptype_t IpAddr::raw_type() const noexcept
234 {
235  return addr_.type;
236 }
237 
239 constexpr bool IpAddr::IsV4() const noexcept
240 {
241  return ETCPAL_IP_IS_V4(&addr_);
242 }
243 
245 constexpr bool IpAddr::IsV6() const noexcept
246 {
247  return ETCPAL_IP_IS_V6(&addr_);
248 }
249 
251 inline bool IpAddr::IsLinkLocal() const noexcept
252 {
253  return etcpal_ip_is_link_local(&addr_);
254 }
255 
257 inline bool IpAddr::IsLoopback() const noexcept
258 {
259  return etcpal_ip_is_loopback(&addr_);
260 }
261 
263 inline bool IpAddr::IsMulticast() const noexcept
264 {
265  return etcpal_ip_is_multicast(&addr_);
266 }
267 
271 inline bool IpAddr::IsWildcard() const noexcept
272 {
273  return etcpal_ip_is_wildcard(&addr_);
274 }
275 
279 inline unsigned int IpAddr::MaskLength() const noexcept
280 {
281  return etcpal_ip_mask_length(&addr_);
282 }
283 
289 inline void IpAddr::SetAddress(uint32_t v4_data) noexcept
290 {
291  ETCPAL_IP_SET_V4_ADDRESS(&addr_, v4_data);
292 }
293 
299 inline void IpAddr::SetAddress(const uint8_t* v6_data) noexcept
300 {
301  ETCPAL_IP_SET_V6_ADDRESS(&addr_, v6_data);
302 }
303 
310 inline void IpAddr::SetAddress(const uint8_t* v6_data, unsigned long scope_id) noexcept
311 {
312  ETCPAL_IP_SET_V6_ADDRESS_WITH_SCOPE_ID(&addr_, v6_data, scope_id);
313 }
314 
318 inline IpAddr IpAddr::FromString(const char* ip_str) noexcept
319 {
320  IpAddr result;
321  if (etcpal_string_to_ip(kEtcPalIpTypeV4, ip_str, &result.addr_) != kEtcPalErrOk)
322  {
323  etcpal_string_to_ip(kEtcPalIpTypeV6, ip_str, &result.addr_);
324  }
325  return result;
326 }
327 
331 inline IpAddr IpAddr::FromString(const std::string& ip_str) noexcept
332 {
333  return FromString(ip_str.c_str());
334 }
335 
339 inline IpAddr IpAddr::WildcardV4() noexcept
340 {
341  return Wildcard(IpAddrType::kV4);
342 }
343 
347 inline IpAddr IpAddr::WildcardV6() noexcept
348 {
349  return Wildcard(IpAddrType::kV6);
350 }
351 
355 inline IpAddr IpAddr::Wildcard(IpAddrType type) noexcept
356 {
357  IpAddr result;
358  etcpal_ip_set_wildcard(static_cast<etcpal_iptype_t>(type), &result.addr_);
359  return result;
360 }
361 
365 inline IpAddr IpAddr::NetmaskV4(unsigned int mask_length) noexcept
366 {
367  return Netmask(IpAddrType::kV4, mask_length);
368 }
369 
373 inline IpAddr IpAddr::NetmaskV6(unsigned int mask_length) noexcept
374 {
375  return Netmask(IpAddrType::kV6, mask_length);
376 }
377 
381 inline IpAddr IpAddr::Netmask(IpAddrType type, unsigned int mask_length) noexcept
382 {
383  return etcpal_ip_mask_from_length(static_cast<etcpal_iptype_t>(type), mask_length);
384 }
385 
391 class SockAddr
392 {
393 public:
394  ETCPAL_CONSTEXPR_14 SockAddr() noexcept;
395  // Note: this constructor is not explicit by design, to allow implicit conversions e.g.
396  // etcpal::SockAddr sa = etcpal_c_function_that_returns_sockaddr();
397  constexpr SockAddr(const EtcPalSockAddr& c_sa) noexcept;
398  SockAddr& operator=(const EtcPalSockAddr& c_sa) noexcept;
399 
400  ETCPAL_CONSTEXPR_14 SockAddr(uint32_t v4_data, uint16_t port) noexcept;
401  SockAddr(const uint8_t* v6_data, uint16_t port) noexcept;
402  SockAddr(const uint8_t* v6_data, unsigned long scope_id, uint16_t port) noexcept;
403  ETCPAL_CONSTEXPR_14 SockAddr(IpAddr ip, uint16_t port) noexcept;
404 
405  constexpr const EtcPalSockAddr& get() const noexcept;
407  std::string ToString() const;
408  constexpr IpAddr ip() const noexcept;
409  constexpr uint16_t port() const noexcept;
410  constexpr uint32_t v4_data() const noexcept;
411  constexpr const uint8_t* v6_data() const noexcept;
412  std::array<uint8_t, ETCPAL_IPV6_BYTES> ToV6Array() const;
413  constexpr unsigned long scope_id() const noexcept;
414 
415  constexpr bool IsValid() const noexcept;
416  constexpr IpAddrType type() const noexcept;
417  constexpr etcpal_iptype_t raw_type() const noexcept;
418  constexpr bool IsV4() const noexcept;
419  constexpr bool IsV6() const noexcept;
420  bool IsLinkLocal() const noexcept;
421  bool IsLoopback() const noexcept;
422  bool IsMulticast() const noexcept;
423  bool IsWildcard() const noexcept;
424 
425  void SetAddress(uint32_t v4_data) noexcept;
426  void SetAddress(const uint8_t* v6_data) noexcept;
427  void SetAddress(const uint8_t* v6_data, unsigned long scope_id) noexcept;
428  void SetAddress(const IpAddr& ip) noexcept;
429  void SetPort(uint16_t port) noexcept;
430 
431 private:
433 };
434 
437 {
438  ETCPAL_IP_SET_INVALID(&addr_.ip);
439 }
440 
442 constexpr SockAddr::SockAddr(const EtcPalSockAddr& c_sa) noexcept : addr_(c_sa)
443 {
444 }
445 
447 inline SockAddr& SockAddr::operator=(const EtcPalSockAddr& c_sa) noexcept
448 {
449  addr_ = c_sa;
450  return *this;
451 }
452 
456 ETCPAL_CONSTEXPR_14_OR_INLINE SockAddr::SockAddr(uint32_t v4_data, uint16_t port) noexcept
457 {
458  ETCPAL_IP_SET_V4_ADDRESS(&addr_.ip, v4_data);
459  addr_.port = port;
460 }
461 
465 inline SockAddr::SockAddr(const uint8_t* v6_data, uint16_t port) noexcept
466 {
467  ETCPAL_IP_SET_V6_ADDRESS(&addr_.ip, v6_data);
468  addr_.port = port;
469 }
470 
478 inline SockAddr::SockAddr(const uint8_t* v6_data, unsigned long scope_id, uint16_t port) noexcept
479 {
480  ETCPAL_IP_SET_V6_ADDRESS_WITH_SCOPE_ID(&addr_.ip, v6_data, scope_id);
481  addr_.port = port;
482 }
483 
488 {
489  addr_.ip = ip.get();
490  addr_.port = port;
491 }
492 
494 constexpr const EtcPalSockAddr& SockAddr::get() const noexcept
495 {
496  return addr_;
497 }
498 
501 {
502  return addr_;
503 }
504 
510 inline std::string SockAddr::ToString() const
511 {
512  if (ETCPAL_IP_IS_V4(&addr_.ip))
513  return ip().ToString() + ':' + std::to_string(addr_.port);
514  if (ETCPAL_IP_IS_V6(&addr_.ip))
515  return '[' + ip().ToString() + "]:" + std::to_string(addr_.port);
516  return {};
517 }
518 
520 constexpr IpAddr SockAddr::ip() const noexcept
521 {
522  return addr_.ip;
523 }
524 
526 constexpr uint16_t SockAddr::port() const noexcept
527 {
528  return addr_.port;
529 }
530 
536 constexpr uint32_t SockAddr::v4_data() const noexcept
537 {
538  return ETCPAL_IP_V4_ADDRESS(&addr_.ip);
539 }
540 
545 constexpr const uint8_t* SockAddr::v6_data() const noexcept
546 {
547  return ETCPAL_IP_V6_ADDRESS(&addr_.ip);
548 }
549 
554 inline std::array<uint8_t, ETCPAL_IPV6_BYTES> SockAddr::ToV6Array() const
555 {
556  // RVO should hopefully make this only a single copy
557  std::array<uint8_t, ETCPAL_IPV6_BYTES> arr; // NOLINT(cppcoreguidelines-pro-type-member-init)
558  std::memcpy(arr.data(), ETCPAL_IP_V6_ADDRESS(&addr_.ip), ETCPAL_IPV6_BYTES);
559  return arr;
560 }
561 
571 constexpr unsigned long SockAddr::scope_id() const noexcept
572 {
573  return ETCPAL_IP_V6_SCOPE_ID(&addr_.ip);
574 }
575 
577 constexpr bool SockAddr::IsValid() const noexcept
578 {
579  return !ETCPAL_IP_IS_INVALID(&addr_.ip);
580 }
581 
583 constexpr IpAddrType SockAddr::type() const noexcept
584 {
585  return static_cast<IpAddrType>(addr_.ip.type);
586 }
587 
589 constexpr etcpal_iptype_t SockAddr::raw_type() const noexcept
590 {
591  return addr_.ip.type;
592 }
593 
595 constexpr bool SockAddr::IsV4() const noexcept
596 {
597  return ETCPAL_IP_IS_V4(&addr_.ip);
598 }
599 
601 constexpr bool SockAddr::IsV6() const noexcept
602 {
603  return ETCPAL_IP_IS_V6(&addr_.ip);
604 }
605 
607 inline bool SockAddr::IsLinkLocal() const noexcept
608 {
609  return etcpal_ip_is_link_local(&addr_.ip);
610 }
611 
613 inline bool SockAddr::IsLoopback() const noexcept
614 {
615  return etcpal_ip_is_loopback(&addr_.ip);
616 }
617 
619 inline bool SockAddr::IsMulticast() const noexcept
620 {
621  return etcpal_ip_is_multicast(&addr_.ip);
622 }
623 
627 inline bool SockAddr::IsWildcard() const noexcept
628 {
629  return etcpal_ip_is_wildcard(&addr_.ip);
630 }
631 
637 inline void SockAddr::SetAddress(uint32_t v4_data) noexcept
638 {
639  ETCPAL_IP_SET_V4_ADDRESS(&addr_.ip, v4_data);
640 }
641 
647 inline void SockAddr::SetAddress(const uint8_t* v6_data) noexcept
648 {
649  ETCPAL_IP_SET_V6_ADDRESS(&addr_.ip, v6_data);
650 }
651 
658 inline void SockAddr::SetAddress(const uint8_t* v6_data, unsigned long scope_id) noexcept
659 {
660  ETCPAL_IP_SET_V6_ADDRESS_WITH_SCOPE_ID(&addr_.ip, v6_data, scope_id);
661 }
662 
665 inline void SockAddr::SetAddress(const IpAddr& ip) noexcept
666 {
667  addr_.ip = ip.get();
668 }
669 
672 inline void SockAddr::SetPort(uint16_t port) noexcept
673 {
674  addr_.port = port;
675 }
676 
681 class MacAddr
682 {
683 public:
685  MacAddr() = default;
686  // Note: this constructor is not explicit by design, to allow implicit conversions e.g.
687  // etcpal::MacAddr sa = etcpal_c_function_that_returns_macaddr();
688  constexpr MacAddr(const EtcPalMacAddr& c_mac) noexcept;
689  MacAddr& operator=(const EtcPalMacAddr& c_mac) noexcept;
690  explicit MacAddr(const uint8_t* mac_data) noexcept;
691 
692  constexpr const EtcPalMacAddr& get() const noexcept;
694  std::string ToString() const;
695  constexpr const uint8_t* data() const noexcept;
696  std::array<uint8_t, ETCPAL_MAC_BYTES> ToArray() const noexcept;
697 
698  bool IsNull() const noexcept;
699 
700  static MacAddr FromString(const char* mac_str) noexcept;
701  static MacAddr FromString(const std::string& mac_str) noexcept;
702 
703 private:
704  EtcPalMacAddr addr_{};
705 };
706 
708 constexpr MacAddr::MacAddr(const EtcPalMacAddr& c_mac) noexcept : addr_(c_mac)
709 {
710 }
711 
713 inline MacAddr& MacAddr::operator=(const EtcPalMacAddr& c_mac) noexcept
714 {
715  addr_ = c_mac;
716  return *this;
717 }
718 
721 inline MacAddr::MacAddr(const uint8_t* mac_data) noexcept
722 {
723  std::memcpy(addr_.data, mac_data, ETCPAL_MAC_BYTES);
724 }
725 
727 constexpr const EtcPalMacAddr& MacAddr::get() const noexcept
728 {
729  return addr_;
730 }
731 
734 {
735  return addr_;
736 }
737 
741 inline std::string MacAddr::ToString() const
742 {
743  std::array<char, ETCPAL_MAC_STRING_BYTES> str_buf; // NOLINT(cppcoreguidelines-pro-type-member-init)
744  etcpal_mac_to_string(&addr_, str_buf.data());
745  return {str_buf.data()};
746 }
747 
750 constexpr const uint8_t* MacAddr::data() const noexcept
751 {
752  return addr_.data;
753 }
754 
758 inline std::array<uint8_t, ETCPAL_MAC_BYTES> MacAddr::ToArray() const noexcept
759 {
760  // RVO should hopefully make this only a single copy
761  std::array<uint8_t, ETCPAL_MAC_BYTES> arr; // NOLINT(cppcoreguidelines-pro-type-member-init)
762  std::memcpy(arr.data(), addr_.data, ETCPAL_MAC_BYTES);
763  return arr;
764 }
765 
767 inline bool MacAddr::IsNull() const noexcept
768 {
769  return ETCPAL_MAC_IS_NULL(&addr_);
770 }
771 
775 inline MacAddr MacAddr::FromString(const char* mac_str) noexcept
776 {
777  MacAddr result;
778  etcpal_string_to_mac(mac_str, &result.addr_);
779  return result;
780 }
781 
785 inline MacAddr MacAddr::FromString(const std::string& mac_str) noexcept
786 {
787  return FromString(mac_str.c_str());
788 }
789 
791 
792 namespace detail
793 {
794 class NetintIndexType
795 {
796 };
797 } // namespace detail
798 
800 
806 
810 {
811 public:
812  NetintInfo() = default;
813  constexpr NetintInfo(const EtcPalNetintInfo& c_info) noexcept;
814  NetintInfo& operator=(const EtcPalNetintInfo& c_info) noexcept;
815 
816  constexpr const EtcPalNetintInfo& get() const noexcept;
817 
818  constexpr NetintIndex index() const noexcept;
819  constexpr IpAddr addr() const noexcept;
820  constexpr IpAddr mask() const noexcept;
821  constexpr MacAddr mac() const noexcept;
822  std::string id() const noexcept;
823  std::string friendly_name() const noexcept;
824  constexpr bool is_default() const noexcept;
825 
826  constexpr bool IsValid() const noexcept;
827  constexpr operator NetintIndex() const noexcept;
828 
829 private:
830  EtcPalNetintInfo info_{};
831 };
832 
834 constexpr NetintInfo::NetintInfo(const EtcPalNetintInfo& c_info) noexcept : info_(c_info)
835 {
836 }
837 
839 inline NetintInfo& NetintInfo::operator=(const EtcPalNetintInfo& c_info) noexcept
840 {
841  info_ = c_info;
842  return *this;
843 }
844 
846 constexpr const EtcPalNetintInfo& NetintInfo::get() const noexcept
847 {
848  return info_;
849 }
850 
857 constexpr NetintIndex NetintInfo::index() const noexcept
858 {
859  return NetintIndex(info_.index);
860 }
861 
863 constexpr IpAddr NetintInfo::addr() const noexcept
864 {
865  return info_.addr;
866 }
867 
869 constexpr IpAddr NetintInfo::mask() const noexcept
870 {
871  return info_.mask;
872 }
873 
875 constexpr MacAddr NetintInfo::mac() const noexcept
876 {
877  return info_.mac;
878 }
879 
886 inline std::string NetintInfo::id() const noexcept
887 {
888  return info_.id;
889 }
890 
896 inline std::string NetintInfo::friendly_name() const noexcept
897 {
898  return info_.friendly_name;
899 }
900 
906 constexpr bool NetintInfo::is_default() const noexcept
907 {
908  return info_.is_default;
909 }
910 
912 constexpr bool NetintInfo::IsValid() const noexcept
913 {
914  return index().IsValid();
915 }
916 
918 constexpr NetintInfo::operator NetintIndex() const noexcept
919 {
920  return index();
921 }
922 
924 // Operators
926 
929 
932 
933 // Special operators for comparing with the underlying types
934 
935 inline bool operator==(const EtcPalIpAddr& c_ip, const IpAddr& ip) noexcept
936 {
937  return c_ip == ip.get();
938 }
939 
940 inline bool operator!=(const EtcPalIpAddr& c_ip, const IpAddr& ip) noexcept
941 {
942  return !(c_ip == ip);
943 }
944 
945 inline bool operator==(const IpAddr& ip, const EtcPalIpAddr& c_ip) noexcept
946 {
947  return ip.get() == c_ip;
948 }
949 
950 inline bool operator!=(const IpAddr& ip, const EtcPalIpAddr& c_ip) noexcept
951 {
952  return !(ip == c_ip);
953 }
954 
955 inline bool operator==(const EtcPalSockAddr& c_ip, const SockAddr& ip) noexcept
956 {
957  return c_ip == ip.get();
958 }
959 
960 inline bool operator!=(const EtcPalSockAddr& c_ip, const SockAddr& ip) noexcept
961 {
962  return !(c_ip == ip);
963 }
964 
965 inline bool operator==(const SockAddr& ip, const EtcPalSockAddr& c_ip) noexcept
966 {
967  return ip.get() == c_ip;
968 }
969 
970 inline bool operator!=(const SockAddr& ip, const EtcPalSockAddr& c_ip) noexcept
971 {
972  return !(ip == c_ip);
973 }
974 
975 inline bool operator==(const EtcPalMacAddr& c_mac, const MacAddr& mac) noexcept
976 {
977  return c_mac == mac.get();
978 }
979 
980 inline bool operator!=(const EtcPalMacAddr& c_mac, const MacAddr& mac) noexcept
981 {
982  return !(c_mac == mac);
983 }
984 
985 inline bool operator==(const MacAddr& mac, const EtcPalMacAddr& c_mac) noexcept
986 {
987  return mac.get() == c_mac;
988 }
989 
990 inline bool operator!=(const MacAddr& mac, const EtcPalMacAddr& c_mac) noexcept
991 {
992  return !(mac == c_mac);
993 }
994 
995 inline bool operator==(const EtcPalNetintInfo& c_info, const NetintInfo& info) noexcept
996 {
997  return c_info == info.get();
998 }
999 
1000 inline bool operator!=(const EtcPalNetintInfo& c_info, const NetintInfo& info) noexcept
1001 {
1002  return !(c_info == info);
1003 }
1004 
1005 inline bool operator==(const NetintInfo& info, const EtcPalNetintInfo& c_info) noexcept
1006 {
1007  return info.get() == c_info;
1008 }
1009 
1010 inline bool operator!=(const NetintInfo& info, const EtcPalNetintInfo& c_info) noexcept
1011 {
1012  return !(info == c_info);
1013 }
1014 
1015 // Standard operators
1016 
1017 inline bool operator==(const IpAddr& a, const IpAddr& b) noexcept
1018 {
1019  return a.get() == b.get();
1020 }
1021 
1022 inline bool operator!=(const IpAddr& a, const IpAddr& b) noexcept
1023 {
1024  return !(a == b);
1025 }
1026 
1027 inline bool operator<(const IpAddr& a, const IpAddr& b) noexcept
1028 {
1029  return a.get() < b.get();
1030 }
1031 
1032 inline bool operator>(const IpAddr& a, const IpAddr& b) noexcept
1033 {
1034  return b < a;
1035 }
1036 
1037 inline bool operator<=(const IpAddr& a, const IpAddr& b) noexcept
1038 {
1039  return !(b < a);
1040 }
1041 
1042 inline bool operator>=(const IpAddr& a, const IpAddr& b) noexcept
1043 {
1044  return !(a < b);
1045 }
1046 
1047 inline bool operator==(const SockAddr& a, const SockAddr& b) noexcept
1048 {
1049  return a.get() == b.get();
1050 }
1051 
1052 inline bool operator!=(const SockAddr& a, const SockAddr& b) noexcept
1053 {
1054  return !(a == b);
1055 }
1056 
1057 inline bool operator<(const SockAddr& a, const SockAddr& b) noexcept
1058 {
1059  return a.get() < b.get();
1060 }
1061 
1062 inline bool operator>(const SockAddr& a, const SockAddr& b) noexcept
1063 {
1064  return b < a;
1065 }
1066 
1067 inline bool operator<=(const SockAddr& a, const SockAddr& b) noexcept
1068 {
1069  return !(b < a);
1070 }
1071 
1072 inline bool operator>=(const SockAddr& a, const SockAddr& b) noexcept
1073 {
1074  return !(a < b);
1075 }
1076 
1077 inline bool operator==(const MacAddr& a, const MacAddr& b) noexcept
1078 {
1079  return a.get() == b.get();
1080 }
1081 
1082 inline bool operator!=(const MacAddr& a, const MacAddr& b) noexcept
1083 {
1084  return !(a == b);
1085 }
1086 
1087 inline bool operator<(const MacAddr& a, const MacAddr& b) noexcept
1088 {
1089  return a.get() < b.get();
1090 }
1091 
1092 inline bool operator>(const MacAddr& a, const MacAddr& b) noexcept
1093 {
1094  return b < a;
1095 }
1096 
1097 inline bool operator<=(const MacAddr& a, const MacAddr& b) noexcept
1098 {
1099  return !(b < a);
1100 }
1101 
1102 inline bool operator>=(const MacAddr& a, const MacAddr& b) noexcept
1103 {
1104  return !(a < b);
1105 }
1106 
1107 inline bool operator==(const NetintInfo& a, const NetintInfo& b) noexcept
1108 {
1109  return a.get() == b.get();
1110 }
1111 
1112 inline bool operator!=(const NetintInfo& a, const NetintInfo& b) noexcept
1113 {
1114  return !(a == b);
1115 }
1116 
1117 inline bool operator<(const NetintInfo& a, const NetintInfo& b) noexcept
1118 {
1119  return a.get() < b.get();
1120 }
1121 
1122 inline bool operator>(const NetintInfo& a, const NetintInfo& b) noexcept
1123 {
1124  return b < a;
1125 }
1126 
1127 inline bool operator<=(const NetintInfo& a, const NetintInfo& b) noexcept
1128 {
1129  return !(b < a);
1130 }
1131 
1132 inline bool operator>=(const NetintInfo& a, const NetintInfo& b) noexcept
1133 {
1134  return !(a < b);
1135 }
1136 
1139 
1140 }; // namespace etcpal
1141 
1143 
1144 // Inject new std::hash specializations for etcpal::IpAddr, SockAddr, and MacAddr, so that they can be used in
1145 // hash-based containers (e.g. unordered_map and unordered_set) without a user needing to create a hash specialization.
1146 //
1147 // The std::hash specializations use an efficient combination of hashes of the underlying data.
1148 namespace std
1149 {
1150 template <>
1151 struct hash<::etcpal::IpAddr>
1152 {
1153  std::size_t operator()(const ::etcpal::IpAddr& addr) const noexcept
1154  {
1155  size_t seed = 0u;
1156 
1157  if (addr.IsV6())
1158  {
1159  for (int i = 0; i < ETCPAL_IPV6_BYTES; ++i)
1160  ::etcpal::HashCombine(seed, addr.v6_data()[i]);
1161 
1162  ::etcpal::HashCombine(seed, addr.scope_id());
1163  }
1164  else if (addr.IsV4())
1165  {
1166  ::etcpal::HashCombine(seed, addr.v4_data());
1167  }
1168 
1169  ::etcpal::HashCombine(seed, static_cast<int>(addr.type()));
1170 
1171  return seed;
1172  }
1173 };
1174 
1175 template <>
1176 struct hash<::etcpal::SockAddr>
1177 {
1178  std::size_t operator()(const ::etcpal::SockAddr& addr) const noexcept
1179  {
1180  size_t seed = 0u;
1181  ::etcpal::HashCombine(seed, addr.ip());
1182  ::etcpal::HashCombine(seed, addr.port());
1183 
1184  return seed;
1185  }
1186 };
1187 
1188 template <>
1189 struct hash<::etcpal::MacAddr>
1190 {
1191  std::size_t operator()(const ::etcpal::MacAddr& addr) const noexcept
1192  {
1193  size_t seed = 0u;
1194  for (int i = 0; i < ETCPAL_MAC_BYTES; ++i)
1195  ::etcpal::HashCombine(seed, addr.data()[i]);
1196 
1197  return seed;
1198  }
1199 };
1200 }; // namespace std
1201 
1202 #endif // ETCPAL_CPP_LOCK_H_
A wrapper class for the EtcPal IP address type.
Definition: inet.h:59
unsigned int MaskLength() const noexcept
The number of consecutive set bits in a netmask.
Definition: inet.h:279
constexpr bool IsV6() const noexcept
Whether an IpAddr contains a valid IPv6 address.
Definition: inet.h:245
static IpAddr NetmaskV4(unsigned int mask_length) noexcept
Construct an IPv4 netmask given a length in bits.
Definition: inet.h:365
constexpr unsigned long scope_id() const noexcept
Get the scope ID of an IPv6 address.
Definition: inet.h:215
std::string ToString() const
Convert the IP address to a string representation.
Definition: inet.h:165
bool IsLinkLocal() const noexcept
Whether an IpAddr contains a link-local address.
Definition: inet.h:251
static IpAddr WildcardV6() noexcept
Construct a wildcard IPv6 address.
Definition: inet.h:347
void SetAddress(uint32_t v4_data) noexcept
Set the IPv4 address data.
Definition: inet.h:289
bool IsMulticast() const noexcept
Whether an IpAddr contains a multicast address.
Definition: inet.h:263
constexpr bool IsV4() const noexcept
Whether an IpAddr contains a valid IPv4 address.
Definition: inet.h:239
constexpr const EtcPalIpAddr & get() const noexcept
Get a const reference to the underlying C type.
Definition: inet.h:151
static IpAddr FromString(const char *ip_str) noexcept
Construct an IpAddr from a string representation.
Definition: inet.h:318
bool IsLoopback() const noexcept
Whether an IpAddr contains a loopback address.
Definition: inet.h:257
static IpAddr Netmask(IpAddrType type, unsigned int mask_length) noexcept
Construct a netmask of the type specifed given a length in bits.
Definition: inet.h:381
ETCPAL_CONSTEXPR_14 IpAddr() noexcept
Constructs an invalid IP address by default.
Definition: inet.h:108
constexpr IpAddrType type() const noexcept
Get the type of the IP address.
Definition: inet.h:227
static IpAddr NetmaskV6(unsigned int mask_length) noexcept
Construct an IPv6 netmask given a length in bits.
Definition: inet.h:373
constexpr bool IsValid() const noexcept
Whether an IpAddr contains a valid IPv4 or IPv6 address.
Definition: inet.h:221
static IpAddr Wildcard(IpAddrType type) noexcept
Construct a wildcard address of the type specified.
Definition: inet.h:355
static IpAddr WildcardV4() noexcept
Construct a wildcard IPv4 address.
Definition: inet.h:339
std::array< uint8_t, ETCPAL_IPV6_BYTES > ToV6Array() const
Get a 16-byte std::array representation of an IPv6 address.
Definition: inet.h:198
bool IsWildcard() const noexcept
Whether an IpAddr contains a wildcard address.
Definition: inet.h:271
constexpr etcpal_iptype_t raw_type() const noexcept
Get the underlying etcpal C type of the IP address.
Definition: inet.h:233
constexpr uint32_t v4_data() const noexcept
Get the raw 32-bit representation of an IPv4 address.
Definition: inet.h:180
IpAddr & operator=(const EtcPalIpAddr &c_ip) noexcept
Assign an instance of the C EtcPalIpAddr type to an instance of this class.
Definition: inet.h:119
constexpr const uint8_t * v6_data() const noexcept
Get the raw 16-byte array representation of an IPv6 address.
Definition: inet.h:189
A wrapper for the EtcPal MAC address type.
Definition: inet.h:682
std::string ToString() const
Convert the MAC address to a string representation.
Definition: inet.h:741
bool IsNull() const noexcept
Whether this MacAddr represents a null (all 0's) MAC address.
Definition: inet.h:767
static MacAddr FromString(const char *mac_str) noexcept
Construct a MacAddr from a string representation.
Definition: inet.h:775
constexpr const uint8_t * data() const noexcept
Get the raw 6-byte array representation of a MAC address.
Definition: inet.h:750
std::array< uint8_t, ETCPAL_MAC_BYTES > ToArray() const noexcept
Get a 6-byte std::array representation of a MAC address.
Definition: inet.h:758
constexpr const EtcPalMacAddr & get() const noexcept
Get a const reference to the underlying C type.
Definition: inet.h:727
MacAddr & operator=(const EtcPalMacAddr &c_mac) noexcept
Assign an instance of the C EtcPalMacAddr type to an instance of this class.
Definition: inet.h:713
MacAddr()=default
Constructs a null MAC address by default.
A wrapper class for the EtcPal netint info type.
Definition: inet.h:810
constexpr IpAddr mask() const noexcept
Get the subnet mask for this interface.
Definition: inet.h:869
constexpr bool is_default() const noexcept
Determine whether this is the default network interface.
Definition: inet.h:906
constexpr const EtcPalNetintInfo & get() const noexcept
Get a const reference to the underlying C type.
Definition: inet.h:846
constexpr bool IsValid() const noexcept
Determine whether this netint info is valid.
Definition: inet.h:912
constexpr IpAddr addr() const noexcept
Get the interface ip address.
Definition: inet.h:863
constexpr NetintIndex index() const noexcept
Get the OS-specific network interface number.
Definition: inet.h:857
std::string friendly_name() const noexcept
Get a user-friendly name for the interface.
Definition: inet.h:896
std::string id() const noexcept
Get the system name for the interface.
Definition: inet.h:886
NetintInfo & operator=(const EtcPalNetintInfo &c_info) noexcept
Assign an instance of the C EtcPalNetintInfo type to an instance of this class.
Definition: inet.h:839
constexpr MacAddr mac() const noexcept
Get the adapter MAC address.
Definition: inet.h:875
A strongly-typed ID with arbitrary internal representation.
Definition: opaque_id.h:118
constexpr bool IsValid() const
Explicitly determine whether an ID is valid.
Definition: opaque_id.h:166
A wrapper for the EtcPal socket address type.
Definition: inet.h:392
constexpr bool IsV6() const noexcept
Whether a SockAddr contains a valid IPv6 address.
Definition: inet.h:601
constexpr unsigned long scope_id() const noexcept
Get the scope ID of the SockAddr's IPv6 address.
Definition: inet.h:571
std::string ToString() const
Convert the IP address and port to a string representation.
Definition: inet.h:510
bool IsLinkLocal() const noexcept
Whether a SockAddr contains a link-local address.
Definition: inet.h:607
void SetAddress(uint32_t v4_data) noexcept
Set the IPv4 address data.
Definition: inet.h:637
bool IsMulticast() const noexcept
Whether a SockAddr contains a multicast address.
Definition: inet.h:619
constexpr IpAddr ip() const noexcept
Get the IP address from the SockAddr.
Definition: inet.h:520
constexpr bool IsV4() const noexcept
Whether a SockAddr contains a valid IPv4 address.
Definition: inet.h:595
bool IsLoopback() const noexcept
Whether a SockAddr contains a loopback address.
Definition: inet.h:613
constexpr const EtcPalSockAddr & get() const noexcept
Get a const reference to the underlying C type.
Definition: inet.h:494
constexpr IpAddrType type() const noexcept
Get the type of the SockAddr's IP address.
Definition: inet.h:583
constexpr bool IsValid() const noexcept
Whether a SockAddr contains a valid IPv4 or IPv6 address.
Definition: inet.h:577
void SetPort(uint16_t port) noexcept
Set the port.
Definition: inet.h:672
std::array< uint8_t, ETCPAL_IPV6_BYTES > ToV6Array() const
Get a 16-byte std::array representation of the SockAddr's IPv6 address.
Definition: inet.h:554
SockAddr & operator=(const EtcPalSockAddr &c_sa) noexcept
Assign an instance of the C EtcPalSockAddr type to an instance of this class.
Definition: inet.h:447
constexpr uint16_t port() const noexcept
Get the port number from the SockAddr.
Definition: inet.h:526
bool IsWildcard() const noexcept
Whether a SockAddr contains a wildcard address.
Definition: inet.h:627
constexpr etcpal_iptype_t raw_type() const noexcept
Get the underlying etcpal C type of the SockAddr's IP address.
Definition: inet.h:589
ETCPAL_CONSTEXPR_14 SockAddr() noexcept
Constructs an invalid SockAddr by default.
Definition: inet.h:436
constexpr uint32_t v4_data() const noexcept
Get the raw 32-bit representation of the SockAddr's IPv4 address.
Definition: inet.h:536
constexpr const uint8_t * v6_data() const noexcept
Get the raw 16-byte array representation of the SockAddr's IPv6 address.
Definition: inet.h:545
Common definitions used by EtcPal C++ wrappers.
void HashCombine(size_t &seed, const T &val)
A function that combines the hash of a new value into an existing seed, based on boost::hash_combine.
Definition: hash.h:52
etcpal::OpaqueId< detail::NetintIndexType, unsigned int, 0 > NetintIndex
A handle that represents a network interface index.
Definition: inet.h:805
IpAddrType
Indicates an IP address family, or an invalid IP address.
Definition: inet.h:48
#define ETCPAL_CONSTEXPR_14
Stand-in for "constexpr" on entities that can only be defined "constexpr" in C++14 or later.
Definition: common.h:53
#define ETCPAL_CONSTEXPR_14_OR_INLINE
Defined to "constexpr" in C++14 or later, "inline" earlier.
Definition: common.h:54
@ kEtcPalErrOk
The call was successful, no error occurred.
Definition: error.h:51
EtcPalIpAddr etcpal_ip_mask_from_length(etcpal_iptype_t type, unsigned int mask_length)
Create a netmask given a length in bits.
Definition: inet.c:351
#define ETCPAL_MAC_BYTES
The number of bytes in a MAC address.
Definition: inet.h:317
#define ETCPAL_IP_V4_ADDRESS(etcpal_ip_ptr)
Get the IPv4 address from a EtcPalIpAddr.
Definition: inet.h:230
#define ETCPAL_IP_IS_V4(etcpal_ip_ptr)
Determine whether a EtcPalIpAddr contains an IPv4 address.
Definition: inet.h:205
#define ETCPAL_IP_IS_INVALID(etcpal_ip_ptr)
Determine whether a EtcPalIpAddr contains an invalid address.
Definition: inet.h:219
void etcpal_ip_set_wildcard(etcpal_iptype_t type, EtcPalIpAddr *ip)
Initialize a EtcPalIpAddr with a wildcard address.
Definition: inet.c:176
#define ETCPAL_IP_SET_V4_ADDRESS(etcpal_ip_ptr, val)
Set the IPv4 address in a EtcPalIpAddr.
Definition: inet.h:262
bool etcpal_ip_is_loopback(const EtcPalIpAddr *ip)
Determine whether a EtcPalIpAddr contains a loopback address.
Definition: inet.c:90
bool etcpal_ip_is_multicast(const EtcPalIpAddr *ip)
Determine whether a EtcPalIpAddr contains a multicast address.
Definition: inet.c:117
etcpal_iptype_t
Used to identify the type of IP address contained in a EtcPalIpAddr.
Definition: inet.h:53
#define ETCPAL_MAC_IS_NULL(macptr)
Determine if a MAC address is null.
Definition: inet.h:346
#define ETCPAL_IP_IS_V6(etcpal_ip_ptr)
Determine whether a EtcPalIpAddr contains an IPv6 address.
Definition: inet.h:212
#define ETCPAL_IP_V6_SCOPE_ID(etcpal_ip_ptr)
Get the IPv6 scope ID from an EtcPalIpAddr.
Definition: inet.h:252
etcpal_error_t etcpal_string_to_ip(etcpal_iptype_t type, const char *src, EtcPalIpAddr *dest)
Convert IPv4 and IPv6 addresses from text to binary form.
unsigned int etcpal_ip_mask_length(const EtcPalIpAddr *netmask)
Get the length in bits of a netmask.
Definition: inet.c:296
bool etcpal_ip_is_link_local(const EtcPalIpAddr *ip)
Determine whether a EtcPalIpAddr contains a link-local address.
Definition: inet.c:62
#define ETCPAL_IP_V6_ADDRESS(etcpal_ip_ptr)
Get the IPv6 address from a EtcPalIpAddr.
Definition: inet.h:241
#define ETCPAL_IP_SET_INVALID(etcpal_ip_ptr)
Set the type field in a EtcPalIpAddr to indicate that it does not contain a valid address.
Definition: inet.h:303
etcpal_error_t etcpal_string_to_mac(const char *src, EtcPalMacAddr *dest)
Create a MAC address from a string representation.
Definition: inet.c:564
#define ETCPAL_IPV6_BYTES
The number of bytes in an IPv6 address.
Definition: inet.h:63
#define ETCPAL_IP_INVALID_INIT
An initializer for an invalid EtcPalIpAddr.
Definition: inet.h:121
#define ETCPAL_IP_SET_V6_ADDRESS(etcpal_ip_ptr, addr_val)
Set the IPv6 address in a EtcPalIpAddr.
Definition: inet.h:278
#define ETCPAL_IP_SET_V6_ADDRESS_WITH_SCOPE_ID(etcpal_ip_ptr, addr_val, scope_id_val)
Set an IPv6 address with an explicit scope ID in a EtcPalIpAddr.
Definition: inet.h:291
bool etcpal_ip_is_wildcard(const EtcPalIpAddr *ip)
Determine whether a EtcPalIpAddr contains a wildcard address.
Definition: inet.c:148
#define ETCPAL_IP_INVALID_INIT_VALUES
A set of initializer values for an invalid EtcPalIpAddr.
Definition: inet.h:110
etcpal_error_t etcpal_mac_to_string(const EtcPalMacAddr *src, char *dest)
Create a string representation of a MAC address.
Definition: inet.c:542
etcpal_error_t etcpal_ip_to_string(const EtcPalIpAddr *src, char *dest)
Convert IPv4 and IPv6 addresses from binary to text form.
@ kEtcPalIpTypeInvalid
This EtcPalIpAddr is not valid.
Definition: inet.h:55
@ kEtcPalIpTypeV4
This EtcPalIpAddr contains an IPv4 address.
Definition: inet.h:57
@ kEtcPalIpTypeV6
This EtcPalIpAddr contains an IPv6 address.
Definition: inet.h:59
Provides the OpaqueId template type and function definitions.
An IP address.
Definition: inet.h:75
etcpal_iptype_t type
The IP address type (IPv4 or IPv6)
Definition: inet.h:77
A MAC address.
Definition: inet.h:321
uint8_t data[ETCPAL_MAC_BYTES]
The 6-byte address data.
Definition: inet.h:322
A description of a single address assigned to a network interface.
Definition: inet.h:355
bool is_default
Whether this is the default network interface.
Definition: inet.h:381
EtcPalIpAddr mask
The subnet mask for this interface.
Definition: inet.h:365
EtcPalMacAddr mac
The adapter MAC address.
Definition: inet.h:367
char id[ETCPAL_NETINTINFO_ID_LEN]
The system name for the interface.
Definition: inet.h:373
char friendly_name[ETCPAL_NETINTINFO_FRIENDLY_NAME_LEN]
A user-friendly name for the interface.
Definition: inet.h:378
unsigned int index
The OS-specific network interface number.
Definition: inet.h:361
EtcPalIpAddr addr
The interface ip address.
Definition: inet.h:363
An IP address with associated interface and port.
Definition: inet.h:311
EtcPalIpAddr ip
IP address.
Definition: inet.h:313
uint16_t port
TCP or UDP port.
Definition: inet.h:312