ip.h 2.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119
  1. #pragma once
  2. #include "socket.h"
  3. #include "hostip.h"
  4. #include <util/system/error.h>
  5. #include <util/system/byteorder.h>
  6. #include <util/generic/string.h>
  7. #include <util/generic/yexception.h>
  8. /// IPv4 address in network format
  9. using TIpHost = ui32;
  10. /// Port number in host format
  11. using TIpPort = ui16;
  12. /*
  13. * ipStr is in 'ddd.ddd.ddd.ddd' format
  14. * returns IPv4 address in inet format
  15. */
  16. static inline TIpHost IpFromString(const char* ipStr) {
  17. in_addr ia;
  18. if (inet_aton(ipStr, &ia) == 0) {
  19. ythrow TSystemError() << "Failed to convert (" << ipStr << ") to ip address";
  20. }
  21. return (ui32)ia.s_addr;
  22. }
  23. static inline char* IpToString(TIpHost ip, char* buf, size_t len) {
  24. if (!inet_ntop(AF_INET, (void*)&ip, buf, (socklen_t)len)) {
  25. ythrow TSystemError() << "Failed to get ip address string";
  26. }
  27. return buf;
  28. }
  29. static inline TString IpToString(TIpHost ip) {
  30. char buf[INET_ADDRSTRLEN];
  31. return TString(IpToString(ip, buf, sizeof(buf)));
  32. }
  33. static inline TIpHost ResolveHost(const char* data, size_t len) {
  34. TIpHost ret;
  35. const TString s(data, len);
  36. if (NResolver::GetHostIP(s.data(), &ret) != 0) {
  37. ythrow TSystemError(NResolver::GetDnsError()) << "can not resolve(" << s << ")";
  38. }
  39. return HostToInet(ret);
  40. }
  41. /// socket address
  42. struct TIpAddress: public sockaddr_in {
  43. inline TIpAddress() noexcept {
  44. Clear();
  45. }
  46. inline TIpAddress(const sockaddr_in& addr) noexcept
  47. : sockaddr_in(addr)
  48. , tmp(0)
  49. {
  50. }
  51. inline TIpAddress(TIpHost ip, TIpPort port) noexcept {
  52. Set(ip, port);
  53. }
  54. inline TIpAddress(TStringBuf ip, TIpPort port) {
  55. Set(ResolveHost(ip.data(), ip.size()), port);
  56. }
  57. inline TIpAddress(const char* ip, TIpPort port) {
  58. Set(ResolveHost(ip, strlen(ip)), port);
  59. }
  60. inline operator sockaddr*() const noexcept {
  61. return (sockaddr*)(sockaddr_in*)this;
  62. }
  63. inline operator socklen_t*() const noexcept {
  64. tmp = sizeof(sockaddr_in);
  65. return (socklen_t*)&tmp;
  66. }
  67. inline operator socklen_t() const noexcept {
  68. tmp = sizeof(sockaddr_in);
  69. return tmp;
  70. }
  71. inline void Clear() noexcept {
  72. Zero((sockaddr_in&)(*this));
  73. }
  74. inline void Set(TIpHost ip, TIpPort port) noexcept {
  75. Clear();
  76. sin_family = AF_INET;
  77. sin_addr.s_addr = ip;
  78. sin_port = HostToInet(port);
  79. }
  80. inline TIpHost Host() const noexcept {
  81. return sin_addr.s_addr;
  82. }
  83. inline TIpPort Port() const noexcept {
  84. return InetToHost(sin_port);
  85. }
  86. private:
  87. // required for "operator socklen_t*()"
  88. mutable socklen_t tmp;
  89. };