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