IP4.h 3.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115
  1. #pragma once
  2. #include "common.h"
  3. #include <WiFi.h>
  4. #include <lwip/inet.h>
  5. #include <esp_wifi.h>
  6. //
  7. // There are no less than 3 different types for IP addresses used
  8. // by different APIs. This class attempts to unify them to mask the
  9. // differences.
  10. //
  11. class IP4 {
  12. private:
  13. union {
  14. uint8_t b[4];
  15. uint32_t l;
  16. };
  17. // assumes gcc
  18. static constexpr uint32_t netswap(uint32_t v) {
  19. #if __BYTE_ORDER__ == __ORDER_BIG_ENDIAN__
  20. return v;
  21. #else
  22. return __builtin_bswap32(v);
  23. #endif
  24. }
  25. static constexpr uint32_t hostmask(unsigned int n) {
  26. return n >= 32 ? 0 : netswap(((uint32_t)1 << n)-1);
  27. }
  28. public:
  29. constexpr IP4() : l{0} { }
  30. constexpr IP4(nullptr_t) : l{0} { }
  31. constexpr IP4(int ll) : l{(uint32_t)ll} { }
  32. constexpr IP4(uint32_t ll) : l{ll} { }
  33. constexpr IP4(uint8_t b0, uint8_t b1, uint8_t b2, uint8_t b3) :
  34. b{b0,b1,b2,b3} { }
  35. IP4(const IPAddress & ip) : l{ip} { }
  36. constexpr IP4(const ip_addr_t & ip) :
  37. l{ip.type == IPADDR_TYPE_V4 ? ip.u_addr.ip4.addr : 0} { }
  38. constexpr IP4(const esp_ip_addr_t & ip) :
  39. l{ip.type == IPADDR_TYPE_V4 ? ip.u_addr.ip4.addr : 0} { }
  40. constexpr IP4(const IP4 &nip, const IP4 &hip, unsigned int n) :
  41. l{(nip.l & ~hostmask(n)) | (hip.l & hostmask(n))} { }
  42. constexpr IP4(const IP4 &nip, const IP4 &hip, const IP4 &mask) :
  43. l{(nip.l & ~mask.l) | (hip.l & mask.l)} { }
  44. IP4(const char *str);
  45. operator uint32_t () const { return l; }
  46. operator IPAddress () const { return IPAddress(l); }
  47. constexpr operator ip_addr_t () const {
  48. return ip_addr_t {
  49. .u_addr = {.ip4 = {.addr = l}},
  50. .type = IPADDR_TYPE_V4
  51. };
  52. }
  53. constexpr operator esp_ip_addr_t () const {
  54. return esp_ip_addr_t {
  55. .u_addr = {.ip4 = {.addr = l}},
  56. .type = IPADDR_TYPE_V4
  57. };
  58. }
  59. //
  60. // XXX: for C++20, this should implement operator <=>.
  61. //
  62. constexpr operator bool () const { return l != 0; }
  63. constexpr bool operator ! () const { return l == 0; }
  64. constexpr bool operator == (const IP4 &b) const { return l == b.l; }
  65. constexpr bool operator != (const IP4 &b) const { return l != b.l; }
  66. constexpr bool operator < (const IP4 &b) const {
  67. return netswap(l) < netswap(b.l);
  68. }
  69. constexpr bool operator >= (const IP4 &b) const {
  70. return netswap(l) >= netswap(b.l);
  71. }
  72. constexpr bool operator <= (const IP4 &b) const {
  73. return netswap(l) <= netswap(b.l);
  74. }
  75. constexpr bool operator > (const IP4 &b) const {
  76. return netswap(l) > netswap(b.l);
  77. }
  78. #ifdef __cpp_impl_three_way_comparison
  79. constexpr auto operator <=> (const IP4 &b) const {
  80. return netswap(l) <=> netswap(b.l);
  81. }
  82. #endif
  83. constexpr IP4 operator & (const IP4 &b) const { return IP4(l & b.l); }
  84. constexpr IP4 operator | (const IP4 &b) const { return IP4(l | b.l); }
  85. constexpr IP4 operator ^ (const IP4 &b) const { return IP4(l ^ b.l); }
  86. constexpr IP4 operator ~ () const { return IP4(~l); }
  87. constexpr IP4 operator / (unsigned int n) const {
  88. return IP4(l & ~hostmask(n));
  89. }
  90. constexpr IP4 operator % (unsigned int n) const {
  91. return IP4(l & hostmask(n));
  92. }
  93. constexpr IP4 operator + (uint32_t n) const {
  94. return IP4(netswap(netswap(l) + n));
  95. }
  96. constexpr IP4 operator - (uint32_t n) const {
  97. return IP4(netswap(netswap(l) - n));
  98. }
  99. constexpr int32_t operator - (const IP4 &b) const {
  100. return netswap(l) - netswap(b.l);
  101. }
  102. constexpr uint8_t operator [] (size_t n) const { return b[n]; }
  103. uint8_t & operator [] (size_t n) { return b[n]; }
  104. const char *cstr();
  105. };
  106. constexpr IP4 null_ip((uint32_t)0);
  107. constexpr IP4 any_ip(~(uint32_t)0);