Logo
~Sockets~
~Examples~
~Contact~


Ipv6Address.cpp

Go to the documentation of this file.
00001 
00006 /*
00007 Copyright (C) 2007  Anders Hedstrom
00008 
00009 This program is free software; you can redistribute it and/or
00010 modify it under the terms of the GNU General Public License
00011 as published by the Free Software Foundation; either version 2
00012 of the License, or (at your option) any later version.
00013 
00014 This program is distributed in the hope that it will be useful,
00015 but WITHOUT ANY WARRANTY; without even the implied warranty of
00016 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00017 GNU General Public License for more details.
00018 
00019 You should have received a copy of the GNU General Public License
00020 along with this program; if not, write to the Free Software
00021 Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
00022 */
00023 #include "Ipv6Address.h"
00024 #ifdef ENABLE_IPV6
00025 
00026 #include "Utility.h"
00027 #include "Parse.h"
00028 #ifndef _WIN32
00029 #include <netdb.h>
00030 #endif
00031 #ifdef IPPROTO_IPV6
00032 
00033 #ifdef SOCKETS_NAMESPACE
00034 namespace SOCKETS_NAMESPACE {
00035 #endif
00036 
00037 
00038 Ipv6Address::Ipv6Address(port_t port) : m_valid(true)
00039 {
00040         memset(&m_addr, 0, sizeof(m_addr));
00041         m_addr.sin6_family = AF_INET6;
00042         m_addr.sin6_port = htons( port );
00043 }
00044 
00045 
00046 Ipv6Address::Ipv6Address(struct in6_addr& a,port_t port) : m_valid(true)
00047 {
00048         memset(&m_addr, 0, sizeof(m_addr));
00049         m_addr.sin6_family = AF_INET6;
00050         m_addr.sin6_port = htons( port );
00051         m_addr.sin6_addr = a;
00052 }
00053 
00054 
00055 Ipv6Address::Ipv6Address(const std::string& host,port_t port) : m_valid(false)
00056 {
00057         memset(&m_addr, 0, sizeof(m_addr));
00058         m_addr.sin6_family = AF_INET6;
00059         m_addr.sin6_port = htons( port );
00060         {
00061                 struct in6_addr a;
00062                 if (Utility::u2ip(host, a))
00063                 {
00064                         m_addr.sin6_addr = a;
00065                         m_valid = true;
00066                 }
00067         }
00068 }
00069 
00070 
00071 Ipv6Address::Ipv6Address(struct sockaddr_in6& sa)
00072 {
00073         m_addr = sa;
00074         m_valid = sa.sin6_family == AF_INET6;
00075 }
00076 
00077 
00078 Ipv6Address::~Ipv6Address()
00079 {
00080 }
00081 
00082 
00083 Ipv6Address::operator struct sockaddr *()
00084 {
00085         return (struct sockaddr *)&m_addr;
00086 }
00087 
00088 
00089 Ipv6Address::operator socklen_t()
00090 {
00091         return sizeof(struct sockaddr_in6);
00092 }
00093 
00094 
00095 void Ipv6Address::SetPort(port_t port)
00096 {
00097         m_addr.sin6_port = htons( port );
00098 }
00099 
00100 
00101 port_t Ipv6Address::GetPort()
00102 {
00103         return ntohs( m_addr.sin6_port );
00104 }
00105 
00106 
00107 bool Ipv6Address::Resolve(const std::string& hostname,struct in6_addr& a)
00108 {
00109         struct sockaddr_in6 sa;
00110         memset(&a, 0, sizeof(a));
00111         if (Utility::isipv6(hostname))
00112         {
00113                 if (!Utility::u2ip(hostname, sa, AI_NUMERICHOST))
00114                         return false;
00115                 a = sa.sin6_addr;
00116                 return true;
00117         }
00118         if (!Utility::u2ip(hostname, sa))
00119                 return false;
00120         a = sa.sin6_addr;
00121         return true;
00122 }
00123 
00124 
00125 bool Ipv6Address::Reverse(struct in6_addr& a,std::string& name)
00126 {
00127         struct sockaddr_in6 sa;
00128         memset(&sa, 0, sizeof(sa));
00129         sa.sin6_family = AF_INET6;
00130         sa.sin6_addr = a;
00131         return Utility::reverse((struct sockaddr *)&sa, sizeof(sa), name);
00132 }
00133 
00134 
00135 std::string Ipv6Address::Convert(bool include_port)
00136 {
00137         if (include_port)
00138                 return Convert(m_addr.sin6_addr) + ":" + Utility::l2string(GetPort());
00139         return Convert(m_addr.sin6_addr);
00140 }
00141 
00142 
00143 std::string Ipv6Address::Convert(struct in6_addr& a,bool mixed)
00144 {
00145         char slask[100]; // l2ip temporary
00146         *slask = 0;
00147         unsigned int prev = 0;
00148         bool skipped = false;
00149         bool ok_to_skip = true;
00150         if (mixed)
00151         {
00152                 unsigned short x;
00153                 unsigned short addr16[8];
00154                 memcpy(addr16, &a, sizeof(addr16));
00155                 for (size_t i = 0; i < 6; i++)
00156                 {
00157                         x = ntohs(addr16[i]);
00158                         if (*slask && (x || !ok_to_skip || prev))
00159                                 strcat(slask,":");
00160                         if (x || !ok_to_skip)
00161                         {
00162                                 sprintf(slask + strlen(slask),"%x", x);
00163                                 if (x && skipped)
00164                                         ok_to_skip = false;
00165                         }
00166                         else
00167                         {
00168                                 skipped = true;
00169                         }
00170                         prev = x;
00171                 }
00172                 x = ntohs(addr16[6]);
00173                 sprintf(slask + strlen(slask),":%u.%u",x / 256,x & 255);
00174                 x = ntohs(addr16[7]);
00175                 sprintf(slask + strlen(slask),".%u.%u",x / 256,x & 255);
00176         }
00177         else
00178         {
00179                 struct sockaddr_in6 sa;
00180                 memset(&sa, 0, sizeof(sa));
00181                 sa.sin6_family = AF_INET6;
00182                 sa.sin6_addr = a;
00183                 std::string name;
00184                 Utility::reverse((struct sockaddr *)&sa, sizeof(sa), name, NI_NUMERICHOST);
00185                 return name;
00186         }
00187         return slask;
00188 }
00189 
00190 
00191 void Ipv6Address::SetAddress(struct sockaddr *sa)
00192 {
00193         memcpy(&m_addr, sa, sizeof(struct sockaddr_in6));
00194 }
00195 
00196 
00197 int Ipv6Address::GetFamily()
00198 {
00199         return m_addr.sin6_family;
00200 }
00201 
00202 
00203 void Ipv6Address::SetFlowinfo(uint32_t x)
00204 {
00205         m_addr.sin6_flowinfo = x;
00206 }
00207 
00208 
00209 uint32_t Ipv6Address::GetFlowinfo()
00210 {
00211         return m_addr.sin6_flowinfo;
00212 }
00213 
00214 
00215 #ifndef _WIN32
00216 void Ipv6Address::SetScopeId(uint32_t x)
00217 {
00218         m_addr.sin6_scope_id = x;
00219 }
00220 
00221 
00222 uint32_t Ipv6Address::GetScopeId()
00223 {
00224         return m_addr.sin6_scope_id;
00225 }
00226 #endif
00227 
00228 
00229 bool Ipv6Address::IsValid()
00230 {
00231         return m_valid;
00232 }
00233 
00234 
00235 bool Ipv6Address::operator==(SocketAddress& a)
00236 {
00237         if (a.GetFamily() != GetFamily())
00238                 return false;
00239         if ((socklen_t)a != sizeof(m_addr))
00240                 return false;
00241         struct sockaddr *sa = a;
00242         struct sockaddr_in6 *p = (struct sockaddr_in6 *)sa;
00243         if (p -> sin6_port != m_addr.sin6_port)
00244                 return false;
00245         if (memcmp(&p -> sin6_addr, &m_addr.sin6_addr, sizeof(struct in6_addr)))
00246                 return false;
00247         return true;
00248 }
00249 
00250 
00251 std::auto_ptr<SocketAddress> Ipv6Address::GetCopy()
00252 {
00253         return std::auto_ptr<SocketAddress>(new Ipv6Address(m_addr));
00254 }
00255 
00256 
00257 std::string Ipv6Address::Reverse()
00258 {
00259         std::string tmp;
00260         Reverse(m_addr.sin6_addr, tmp);
00261         return tmp;
00262 }
00263 
00264 
00265 #ifdef SOCKETS_NAMESPACE
00266 } // namespace SOCKETS_NAMESPACE {
00267 #endif
00268 #endif // IPPROTO_IPV6
00269 #endif // ENABLE_IPV6
Page, code, and content Copyright (C) 2007 by Anders Hedström
Generated for C++ Sockets by  doxygen 1.4.4