PageRenderTime 43ms CodeModel.GetById 16ms RepoModel.GetById 0ms app.codeStats 0ms

/dep/src/sockets/Ipv6Address.cpp

http://github.com/skyne/NeoCore
C++ | 271 lines | 197 code | 52 blank | 22 comment | 23 complexity | 4797536c75d055905c0114772cad0026 MD5 | raw file
Possible License(s): GPL-2.0, CC-BY-SA-3.0, LGPL-2.1
  1. /**
  2. ** \file Ipv6Address.cpp
  3. ** \date 2006-09-21
  4. ** \author grymse@alhem.net
  5. **/
  6. /*
  7. Copyright (C) 2007 Anders Hedstrom
  8. This program is free software; you can redistribute it and/or
  9. modify it under the terms of the GNU General Public License
  10. as published by the Free Software Foundation; either version 2
  11. of the License, or (at your option) any later version.
  12. This program is distributed in the hope that it will be useful,
  13. but WITHOUT ANY WARRANTY; without even the implied warranty of
  14. MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  15. GNU General Public License for more details.
  16. You should have received a copy of the GNU General Public License
  17. along with this program; if not, write to the Free Software
  18. Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
  19. */
  20. #include "Ipv6Address.h"
  21. #ifdef ENABLE_IPV6
  22. #include "Utility.h"
  23. #include "Parse.h"
  24. #ifndef _WIN32
  25. #include <netdb.h>
  26. #endif
  27. #ifdef IPPROTO_IPV6
  28. #ifdef SOCKETS_NAMESPACE
  29. namespace SOCKETS_NAMESPACE {
  30. #endif
  31. Ipv6Address::Ipv6Address(port_t port) : m_valid(true)
  32. {
  33. memset(&m_addr, 0, sizeof(m_addr));
  34. m_addr.sin6_family = AF_INET6;
  35. m_addr.sin6_port = htons( port );
  36. }
  37. Ipv6Address::Ipv6Address(struct in6_addr& a,port_t port) : m_valid(true)
  38. {
  39. memset(&m_addr, 0, sizeof(m_addr));
  40. m_addr.sin6_family = AF_INET6;
  41. m_addr.sin6_port = htons( port );
  42. m_addr.sin6_addr = a;
  43. }
  44. Ipv6Address::Ipv6Address(const std::string& host,port_t port) : m_valid(false)
  45. {
  46. memset(&m_addr, 0, sizeof(m_addr));
  47. m_addr.sin6_family = AF_INET6;
  48. m_addr.sin6_port = htons( port );
  49. {
  50. struct in6_addr a;
  51. if (Utility::u2ip(host, a))
  52. {
  53. m_addr.sin6_addr = a;
  54. m_valid = true;
  55. }
  56. }
  57. }
  58. Ipv6Address::Ipv6Address(struct sockaddr_in6& sa)
  59. {
  60. m_addr = sa;
  61. m_valid = sa.sin6_family == AF_INET6;
  62. }
  63. Ipv6Address::~Ipv6Address()
  64. {
  65. }
  66. Ipv6Address::operator struct sockaddr *()
  67. {
  68. return (struct sockaddr *)&m_addr;
  69. }
  70. Ipv6Address::operator socklen_t()
  71. {
  72. return sizeof(struct sockaddr_in6);
  73. }
  74. void Ipv6Address::SetPort(port_t port)
  75. {
  76. m_addr.sin6_port = htons( port );
  77. }
  78. port_t Ipv6Address::GetPort()
  79. {
  80. return ntohs( m_addr.sin6_port );
  81. }
  82. bool Ipv6Address::Resolve(const std::string& hostname,struct in6_addr& a)
  83. {
  84. struct sockaddr_in6 sa;
  85. memset(&a, 0, sizeof(a));
  86. if (Utility::isipv6(hostname))
  87. {
  88. if (!Utility::u2ip(hostname, sa, AI_NUMERICHOST))
  89. return false;
  90. a = sa.sin6_addr;
  91. return true;
  92. }
  93. if (!Utility::u2ip(hostname, sa))
  94. return false;
  95. a = sa.sin6_addr;
  96. return true;
  97. }
  98. bool Ipv6Address::Reverse(struct in6_addr& a,std::string& name)
  99. {
  100. struct sockaddr_in6 sa;
  101. memset(&sa, 0, sizeof(sa));
  102. sa.sin6_family = AF_INET6;
  103. sa.sin6_addr = a;
  104. return Utility::reverse((struct sockaddr *)&sa, sizeof(sa), name);
  105. }
  106. std::string Ipv6Address::Convert(bool include_port)
  107. {
  108. if (include_port)
  109. return Convert(m_addr.sin6_addr) + ":" + Utility::l2string(GetPort());
  110. return Convert(m_addr.sin6_addr);
  111. }
  112. std::string Ipv6Address::Convert(struct in6_addr& a,bool mixed)
  113. {
  114. char slask[100]; // l2ip temporary
  115. *slask = 0;
  116. unsigned int prev = 0;
  117. bool skipped = false;
  118. bool ok_to_skip = true;
  119. if (mixed)
  120. {
  121. unsigned short x;
  122. unsigned short addr16[8];
  123. memcpy(addr16, &a, sizeof(addr16));
  124. for (size_t i = 0; i < 6; i++)
  125. {
  126. x = ntohs(addr16[i]);
  127. if (*slask && (x || !ok_to_skip || prev))
  128. strcat(slask,":");
  129. if (x || !ok_to_skip)
  130. {
  131. sprintf(slask + strlen(slask),"%x", x);
  132. if (x && skipped)
  133. ok_to_skip = false;
  134. }
  135. else
  136. {
  137. skipped = true;
  138. }
  139. prev = x;
  140. }
  141. x = ntohs(addr16[6]);
  142. sprintf(slask + strlen(slask),":%u.%u",x / 256,x & 255);
  143. x = ntohs(addr16[7]);
  144. sprintf(slask + strlen(slask),".%u.%u",x / 256,x & 255);
  145. }
  146. else
  147. {
  148. struct sockaddr_in6 sa;
  149. memset(&sa, 0, sizeof(sa));
  150. sa.sin6_family = AF_INET6;
  151. sa.sin6_addr = a;
  152. std::string name;
  153. Utility::reverse((struct sockaddr *)&sa, sizeof(sa), name, NI_NUMERICHOST);
  154. return name;
  155. }
  156. return slask;
  157. }
  158. void Ipv6Address::SetAddress(struct sockaddr *sa)
  159. {
  160. memcpy(&m_addr, sa, sizeof(struct sockaddr_in6));
  161. }
  162. int Ipv6Address::GetFamily()
  163. {
  164. return m_addr.sin6_family;
  165. }
  166. void Ipv6Address::SetFlowinfo(uint32_t x)
  167. {
  168. m_addr.sin6_flowinfo = x;
  169. }
  170. uint32_t Ipv6Address::GetFlowinfo()
  171. {
  172. return m_addr.sin6_flowinfo;
  173. }
  174. #ifndef _WIN32
  175. void Ipv6Address::SetScopeId(uint32_t x)
  176. {
  177. m_addr.sin6_scope_id = x;
  178. }
  179. uint32_t Ipv6Address::GetScopeId()
  180. {
  181. return m_addr.sin6_scope_id;
  182. }
  183. #endif
  184. bool Ipv6Address::IsValid()
  185. {
  186. return m_valid;
  187. }
  188. bool Ipv6Address::operator==(SocketAddress& a)
  189. {
  190. if (a.GetFamily() != GetFamily())
  191. return false;
  192. if ((socklen_t)a != sizeof(m_addr))
  193. return false;
  194. struct sockaddr *sa = a;
  195. struct sockaddr_in6 *p = (struct sockaddr_in6 *)sa;
  196. if (p -> sin6_port != m_addr.sin6_port)
  197. return false;
  198. if (memcmp(&p -> sin6_addr, &m_addr.sin6_addr, sizeof(struct in6_addr)))
  199. return false;
  200. return true;
  201. }
  202. std::auto_ptr<SocketAddress> Ipv6Address::GetCopy()
  203. {
  204. return std::auto_ptr<SocketAddress>(new Ipv6Address(m_addr));
  205. }
  206. std::string Ipv6Address::Reverse()
  207. {
  208. std::string tmp;
  209. Reverse(m_addr.sin6_addr, tmp);
  210. return tmp;
  211. }
  212. #ifdef SOCKETS_NAMESPACE
  213. } // namespace SOCKETS_NAMESPACE {
  214. #endif
  215. #endif // IPPROTO_IPV6
  216. #endif // ENABLE_IPV6