2
0

address.h 3.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160
  1. #ifndef NMRPFLASH_ADDRESS_H
  2. #define NMRPFLASH_ADDRESS_H
  3. #include <boost/asio.hpp>
  4. #include <boost/algorithm/string.hpp>
  5. #include <boost/range/adaptors.hpp>
  6. #include <sys/socket.h>
  7. #include <sys/types.h>
  8. #include <netinet/in.h>
  9. #include <arpa/inet.h>
  10. #include <iterator>
  11. #include <iostream>
  12. #include <variant>
  13. #include <iomanip>
  14. #include <sstream>
  15. #include <string>
  16. #include "util.h"
  17. #if BOOST_OS_WINDOWS
  18. // TODO
  19. #else
  20. # include <ifaddrs.h>
  21. # include <net/if.h>
  22. # if BOOST_OS_LINUX
  23. # include <linux/if_packet.h>
  24. # else
  25. # include <net/if_types.h>
  26. # include <net/if_media.h>
  27. # include <net/if_dl.h>
  28. #endif
  29. #endif
  30. namespace nmrpflash {
  31. typedef boost::asio::ip::address ip_addr;
  32. typedef boost::asio::ip::address_v4 ip4_addr;
  33. typedef boost::asio::ip::address_v6 ip6_addr;
  34. ip_addr ip_from_sockaddr(gsl::not_null<const sockaddr*> addr);
  35. ip4_addr ip4_from_sockaddr(gsl::not_null<const sockaddr_in*> addr);
  36. ip6_addr ip6_from_sockaddr(gsl::not_null<const sockaddr_in6*> addr);
  37. typedef boost::asio::ip::network_v4 ip4_net;
  38. typedef boost::asio::ip::network_v6 ip6_net;
  39. class ip_net
  40. {
  41. public:
  42. ip_net(const ip_addr& addr, const ip_addr& netmask);
  43. bool is_v4() const
  44. { return m_net.index() == 0; }
  45. bool is_v6() const
  46. { return !is_v4(); }
  47. ip4_net to_v4() const
  48. { return std::get<ip4_net>(m_net); }
  49. ip6_net to_v6() const
  50. { return std::get<ip6_net>(m_net); }
  51. friend std::ostream& operator<<(std::ostream& os, const ip_net& net)
  52. {
  53. if (net.is_v4()) {
  54. os << net.to_v4();
  55. } else {
  56. os << net.to_v6();
  57. }
  58. return os;
  59. }
  60. private:
  61. std::variant<ip4_net, ip6_net> m_net;
  62. };
  63. class mac_addr
  64. {
  65. public:
  66. static constexpr size_t length = 6;
  67. mac_addr()
  68. {
  69. memset(m_addr.data(), 0, length);
  70. }
  71. mac_addr(const mac_addr& other)
  72. : mac_addr(&other.m_addr, nullptr)
  73. {}
  74. mac_addr(const uint8_t (&addr)[length])
  75. : mac_addr(addr, nullptr)
  76. {}
  77. mac_addr(const std::string& addr);
  78. bool operator==(const mac_addr& other) const
  79. {
  80. return !memcmp(m_addr.data(), other.m_addr.data(), length);
  81. }
  82. bool operator<(const mac_addr& other) const
  83. {
  84. return memcmp(m_addr.data(), other.m_addr.data(), length) < 0;
  85. }
  86. friend std::ostream& operator<<(std::ostream& os, const mac_addr& addr);
  87. template<class CharT> static mac_addr from_raw(const CharT* addr)
  88. {
  89. static_assert(sizeof(CharT) == 1);
  90. return mac_addr(addr, nullptr);
  91. }
  92. private:
  93. mac_addr(const void* addr, std::nullptr_t)
  94. {
  95. memcpy(m_addr.data(), addr, length);
  96. }
  97. std::array<uint8_t, length> m_addr;
  98. };
  99. #if 0
  100. template<> void
  101. generic_addr<af_ethernet>::copy_to(typename addr_helper_impl<af_ethernet>::sockaddr_type&) = delete;
  102. template<> inline std::string generic_addr<af_ethernet>::to_string() const
  103. {
  104. }
  105. template<> inline bool generic_addr<af_ethernet>::from_string(const std::string& addr)
  106. {
  107. std::vector<std::string> parts;
  108. boost::split(parts, addr, boost::algorithm::is_any_of(":-"));
  109. if (parts.size() != addr_size) {
  110. return false;
  111. }
  112. for (size_t i = 0; i < parts.size(); ++i) {
  113. if (parts[i].size() != 2) {
  114. return false;
  115. }
  116. size_t k;
  117. int n = stoi(parts[i], &k, 16);
  118. if (k != 2 || n < 0 || n > 0xff) {
  119. return false;
  120. }
  121. m_addr[i] = n & 0xff;
  122. }
  123. return true;
  124. }
  125. } // namespace nmrpflash
  126. #endif
  127. }
  128. #endif