00001
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033 #include "Ipv6Address.h"
00034 #ifdef ENABLE_IPV6
00035
00036 #include "Utility.h"
00037 #ifndef _WIN32
00038 #include <netdb.h>
00039 #endif
00040 #ifdef IPPROTO_IPV6
00041 #include <cstdio>
00042
00043 #ifdef SOCKETS_NAMESPACE
00044 namespace SOCKETS_NAMESPACE {
00045 #endif
00046
00047
00048 Ipv6Address::Ipv6Address(port_t port) : m_valid(true)
00049 {
00050 memset(&m_addr, 0, sizeof(m_addr));
00051 m_addr.sin6_family = AF_INET6;
00052 m_addr.sin6_port = htons( port );
00053 }
00054
00055
00056 Ipv6Address::Ipv6Address(struct in6_addr& a,port_t port) : m_valid(true)
00057 {
00058 memset(&m_addr, 0, sizeof(m_addr));
00059 m_addr.sin6_family = AF_INET6;
00060 m_addr.sin6_port = htons( port );
00061 m_addr.sin6_addr = a;
00062 }
00063
00064
00065 Ipv6Address::Ipv6Address(const std::string& host,port_t port) : m_valid(false)
00066 {
00067 memset(&m_addr, 0, sizeof(m_addr));
00068 m_addr.sin6_family = AF_INET6;
00069 m_addr.sin6_port = htons( port );
00070 {
00071 struct in6_addr a;
00072 if (Utility::u2ip(host, a))
00073 {
00074 m_addr.sin6_addr = a;
00075 m_valid = true;
00076 }
00077 }
00078 }
00079
00080
00081 Ipv6Address::Ipv6Address(struct sockaddr_in6& sa)
00082 {
00083 m_addr = sa;
00084 m_valid = sa.sin6_family == AF_INET6;
00085 }
00086
00087
00088 Ipv6Address::~Ipv6Address()
00089 {
00090 }
00091
00092
00093 Ipv6Address::operator struct sockaddr *()
00094 {
00095 return (struct sockaddr *)&m_addr;
00096 }
00097
00098
00099 Ipv6Address::operator socklen_t()
00100 {
00101 return sizeof(struct sockaddr_in6);
00102 }
00103
00104
00105 void Ipv6Address::SetPort(port_t port)
00106 {
00107 m_addr.sin6_port = htons( port );
00108 }
00109
00110
00111 port_t Ipv6Address::GetPort()
00112 {
00113 return ntohs( m_addr.sin6_port );
00114 }
00115
00116
00117 bool Ipv6Address::Resolve(const std::string& hostname,struct in6_addr& a)
00118 {
00119 struct sockaddr_in6 sa;
00120 memset(&a, 0, sizeof(a));
00121 if (Utility::isipv6(hostname))
00122 {
00123 if (!Utility::u2ip(hostname, sa, AI_NUMERICHOST))
00124 return false;
00125 a = sa.sin6_addr;
00126 return true;
00127 }
00128 if (!Utility::u2ip(hostname, sa))
00129 return false;
00130 a = sa.sin6_addr;
00131 return true;
00132 }
00133
00134
00135 bool Ipv6Address::Reverse(struct in6_addr& a,std::string& name)
00136 {
00137 struct sockaddr_in6 sa;
00138 memset(&sa, 0, sizeof(sa));
00139 sa.sin6_family = AF_INET6;
00140 sa.sin6_addr = a;
00141 return Utility::reverse((struct sockaddr *)&sa, sizeof(sa), name);
00142 }
00143
00144
00145 std::string Ipv6Address::Convert(bool include_port)
00146 {
00147 if (include_port)
00148 return Convert(m_addr.sin6_addr) + ":" + Utility::l2string(GetPort());
00149 return Convert(m_addr.sin6_addr);
00150 }
00151
00152
00153 std::string Ipv6Address::Convert(struct in6_addr& a,bool mixed)
00154 {
00155 char slask[100];
00156 *slask = 0;
00157 unsigned int prev = 0;
00158 bool skipped = false;
00159 bool ok_to_skip = true;
00160 if (mixed)
00161 {
00162 unsigned short x;
00163 unsigned short addr16[8];
00164 memcpy(addr16, &a, sizeof(addr16));
00165 for (size_t i = 0; i < 6; i++)
00166 {
00167 x = ntohs(addr16[i]);
00168 if (*slask && (x || !ok_to_skip || prev))
00169 {
00170 #if defined( _WIN32) && !defined(__CYGWIN__)
00171 strcat_s(slask,sizeof(slask),":");
00172 #else
00173 strcat(slask,":");
00174 #endif
00175 }
00176 if (x || !ok_to_skip)
00177 {
00178 snprintf(slask + strlen(slask), sizeof(slask) - strlen(slask),"%x", x);
00179 if (x && skipped)
00180 ok_to_skip = false;
00181 }
00182 else
00183 {
00184 skipped = true;
00185 }
00186 prev = x;
00187 }
00188 x = ntohs(addr16[6]);
00189 snprintf(slask + strlen(slask), sizeof(slask) - strlen(slask),":%u.%u",x / 256,x & 255);
00190 x = ntohs(addr16[7]);
00191 snprintf(slask + strlen(slask), sizeof(slask) - strlen(slask),".%u.%u",x / 256,x & 255);
00192 }
00193 else
00194 {
00195 struct sockaddr_in6 sa;
00196 memset(&sa, 0, sizeof(sa));
00197 sa.sin6_family = AF_INET6;
00198 sa.sin6_addr = a;
00199 std::string name;
00200 Utility::reverse((struct sockaddr *)&sa, sizeof(sa), name, NI_NUMERICHOST);
00201 return name;
00202 }
00203 return slask;
00204 }
00205
00206
00207 void Ipv6Address::SetAddress(struct sockaddr *sa)
00208 {
00209 memcpy(&m_addr, sa, sizeof(struct sockaddr_in6));
00210 }
00211
00212
00213 int Ipv6Address::GetFamily()
00214 {
00215 return m_addr.sin6_family;
00216 }
00217
00218
00219 void Ipv6Address::SetFlowinfo(uint32_t x)
00220 {
00221 m_addr.sin6_flowinfo = x;
00222 }
00223
00224
00225 uint32_t Ipv6Address::GetFlowinfo()
00226 {
00227 return m_addr.sin6_flowinfo;
00228 }
00229
00230
00231 #ifndef _WIN32
00232 void Ipv6Address::SetScopeId(uint32_t x)
00233 {
00234 m_addr.sin6_scope_id = x;
00235 }
00236
00237
00238 uint32_t Ipv6Address::GetScopeId()
00239 {
00240 return m_addr.sin6_scope_id;
00241 }
00242 #endif
00243
00244
00245 bool Ipv6Address::IsValid()
00246 {
00247 return m_valid;
00248 }
00249
00250
00251 bool Ipv6Address::operator==(SocketAddress& a)
00252 {
00253 if (a.GetFamily() != GetFamily())
00254 return false;
00255 if ((socklen_t)a != sizeof(m_addr))
00256 return false;
00257 struct sockaddr *sa = a;
00258 struct sockaddr_in6 *p = (struct sockaddr_in6 *)sa;
00259 if (p -> sin6_port != m_addr.sin6_port)
00260 return false;
00261 if (memcmp(&p -> sin6_addr, &m_addr.sin6_addr, sizeof(struct in6_addr)))
00262 return false;
00263 return true;
00264 }
00265
00266
00267 std::auto_ptr<SocketAddress> Ipv6Address::GetCopy()
00268 {
00269 return std::auto_ptr<SocketAddress>(new Ipv6Address(m_addr));
00270 }
00271
00272
00273 std::string Ipv6Address::Reverse()
00274 {
00275 std::string tmp;
00276 Reverse(m_addr.sin6_addr, tmp);
00277 return tmp;
00278 }
00279
00280
00281 #ifdef SOCKETS_NAMESPACE
00282 }
00283 #endif
00284 #endif // IPPROTO_IPV6
00285 #endif // ENABLE_IPV6
00286