src/network/kernel/qhostaddress.cpp
changeset 0 1918ee327afb
child 4 3b1da2848fc7
equal deleted inserted replaced
-1:000000000000 0:1918ee327afb
       
     1 /****************************************************************************
       
     2 **
       
     3 ** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
       
     4 ** All rights reserved.
       
     5 ** Contact: Nokia Corporation (qt-info@nokia.com)
       
     6 **
       
     7 ** This file is part of the QtNetwork module of the Qt Toolkit.
       
     8 **
       
     9 ** $QT_BEGIN_LICENSE:LGPL$
       
    10 ** No Commercial Usage
       
    11 ** This file contains pre-release code and may not be distributed.
       
    12 ** You may use this file in accordance with the terms and conditions
       
    13 ** contained in the Technology Preview License Agreement accompanying
       
    14 ** this package.
       
    15 **
       
    16 ** GNU Lesser General Public License Usage
       
    17 ** Alternatively, this file may be used under the terms of the GNU Lesser
       
    18 ** General Public License version 2.1 as published by the Free Software
       
    19 ** Foundation and appearing in the file LICENSE.LGPL included in the
       
    20 ** packaging of this file.  Please review the following information to
       
    21 ** ensure the GNU Lesser General Public License version 2.1 requirements
       
    22 ** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
       
    23 **
       
    24 ** In addition, as a special exception, Nokia gives you certain additional
       
    25 ** rights.  These rights are described in the Nokia Qt LGPL Exception
       
    26 ** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
       
    27 **
       
    28 ** If you have questions regarding the use of this file, please contact
       
    29 ** Nokia at qt-info@nokia.com.
       
    30 **
       
    31 **
       
    32 **
       
    33 **
       
    34 **
       
    35 **
       
    36 **
       
    37 **
       
    38 ** $QT_END_LICENSE$
       
    39 **
       
    40 ****************************************************************************/
       
    41 
       
    42 #include "qhostaddress.h"
       
    43 #include "qhostaddress_p.h"
       
    44 #include "qdebug.h"
       
    45 #include "qplatformdefs.h"
       
    46 #include "qstringlist.h"
       
    47 #include "qendian.h"
       
    48 #ifndef QT_NO_DATASTREAM
       
    49 #include <qdatastream.h>
       
    50 #endif
       
    51 #if defined(Q_OS_WINCE)
       
    52 #include <winsock.h>
       
    53 #endif
       
    54 
       
    55 #ifdef QT_LINUXBASE
       
    56 #  include <arpa/inet.h>
       
    57 #endif
       
    58 
       
    59 QT_BEGIN_NAMESPACE
       
    60 
       
    61 #define QT_ENSURE_PARSED(a) \
       
    62     do { \
       
    63         if (!(a)->d->isParsed) \
       
    64             (a)->d->parse(); \
       
    65     } while (0)
       
    66 
       
    67 #ifdef Q_OS_WIN
       
    68 #    if !defined (QT_NO_IPV6)
       
    69 // sockaddr_in6 size changed between old and new SDK
       
    70 // Only the new version is the correct one, so always
       
    71 // use this structure.
       
    72 #if defined(Q_OS_WINCE)
       
    73 #  if !defined(u_char)
       
    74 #    define u_char unsigned char
       
    75 #  endif
       
    76 #  if !defined(u_short)
       
    77 #    define u_short unsigned short
       
    78 #  endif
       
    79 #  if !defined(u_long)
       
    80 #    define u_long unsigned long
       
    81 #  endif
       
    82 #endif
       
    83 struct qt_in6_addr {
       
    84     u_char qt_s6_addr[16];
       
    85 };
       
    86 typedef struct {
       
    87     short   sin6_family;            /* AF_INET6 */
       
    88     u_short sin6_port;              /* Transport level port number */
       
    89     u_long  sin6_flowinfo;          /* IPv6 flow information */
       
    90     struct  qt_in6_addr sin6_addr;  /* IPv6 address */
       
    91     u_long  sin6_scope_id;          /* set of interfaces for a scope */
       
    92 } qt_sockaddr_in6;
       
    93 #    else
       
    94 typedef void * qt_sockaddr_in6 ;
       
    95 #    endif
       
    96 #    ifndef AF_INET6
       
    97 #        define AF_INET6        23  /* Internetwork Version 6 */
       
    98 #    endif
       
    99 #else
       
   100 #define qt_sockaddr_in6 sockaddr_in6
       
   101 #define qt_s6_addr s6_addr
       
   102 #endif
       
   103 
       
   104 
       
   105 class QHostAddressPrivate
       
   106 {
       
   107 public:
       
   108     QHostAddressPrivate();
       
   109 
       
   110     void setAddress(quint32 a_ = 0);
       
   111     void setAddress(const quint8 *a_);
       
   112     void setAddress(const Q_IPV6ADDR &a_);
       
   113 
       
   114     bool parse();
       
   115     void clear();
       
   116 
       
   117     quint32 a;    // IPv4 address
       
   118     Q_IPV6ADDR a6; // IPv6 address
       
   119     QAbstractSocket::NetworkLayerProtocol protocol;
       
   120 
       
   121     QString ipString;
       
   122     bool isParsed;
       
   123     QString scopeId;
       
   124 
       
   125     friend class QHostAddress;
       
   126 };
       
   127 
       
   128 QHostAddressPrivate::QHostAddressPrivate()
       
   129     : a(0), protocol(QAbstractSocket::UnknownNetworkLayerProtocol), isParsed(true)
       
   130 {
       
   131     memset(&a6, 0, sizeof(a6));
       
   132 }
       
   133 
       
   134 void QHostAddressPrivate::setAddress(quint32 a_)
       
   135 {
       
   136     a = a_;
       
   137     protocol = QAbstractSocket::IPv4Protocol;
       
   138     isParsed = true;
       
   139 }
       
   140 
       
   141 void QHostAddressPrivate::setAddress(const quint8 *a_)
       
   142 {
       
   143     for (int i = 0; i < 16; i++)
       
   144         a6[i] = a_[i];
       
   145     protocol = QAbstractSocket::IPv6Protocol;
       
   146     isParsed = true;
       
   147 }
       
   148 
       
   149 void QHostAddressPrivate::setAddress(const Q_IPV6ADDR &a_)
       
   150 {
       
   151     a6 = a_;
       
   152     a = 0;
       
   153     protocol = QAbstractSocket::IPv6Protocol;
       
   154     isParsed = true;
       
   155 }
       
   156 
       
   157 static bool parseIp4(const QString& address, quint32 *addr)
       
   158 {
       
   159     QStringList ipv4 = address.split(QLatin1String("."));
       
   160     if (ipv4.count() != 4)
       
   161         return false;
       
   162 
       
   163     quint32 ipv4Address = 0;
       
   164     for (int i = 0; i < 4; ++i) {
       
   165         bool ok = false;
       
   166         uint byteValue = ipv4.at(i).toUInt(&ok);
       
   167         if (!ok || byteValue > 255)
       
   168             return false;
       
   169 
       
   170         ipv4Address <<= 8;
       
   171         ipv4Address += byteValue;
       
   172     }
       
   173 
       
   174     *addr = ipv4Address;
       
   175     return true;
       
   176 }
       
   177 
       
   178 static bool parseIp6(const QString &address, quint8 *addr, QString *scopeId)
       
   179 {
       
   180     QString tmp = address;
       
   181     int scopeIdPos = tmp.lastIndexOf(QLatin1Char('%'));
       
   182     if (scopeIdPos != -1) {
       
   183         *scopeId = tmp.mid(scopeIdPos + 1);
       
   184         tmp.chop(tmp.size() - scopeIdPos);
       
   185     } else {
       
   186         scopeId->clear();
       
   187     }
       
   188 
       
   189     QStringList ipv6 = tmp.split(QLatin1String(":"));
       
   190     int count = ipv6.count();
       
   191     if (count < 3 || count > 8)
       
   192         return false;
       
   193 
       
   194     int colonColon = tmp.count(QLatin1String("::"));
       
   195     if(count == 8 && colonColon > 1)
       
   196         return false;
       
   197 
       
   198     // address can be compressed with a "::", but that
       
   199     // may only appear once (see RFC 1884)
       
   200     // the statement below means:
       
   201     // if(shortened notation is not used AND
       
   202     // ((pure IPv6 notation AND less than 8 parts) OR
       
   203     // ((mixed IPv4/6 notation AND less than 7 parts)))
       
   204     if(colonColon != 1 && count < (tmp.contains(QLatin1Char('.')) ? 7 : 8))
       
   205         return false;
       
   206 
       
   207     int mc = 16;
       
   208     int fillCount = 9 - count;  // number of 0 words to fill in the middle
       
   209     for (int i = count - 1; i >= 0; --i) {
       
   210         if (mc <= 0)
       
   211             return false;
       
   212 
       
   213         if (ipv6.at(i).isEmpty()) {
       
   214             if (i == count - 1) {
       
   215                 // special case: ":" is last character
       
   216                 if (!ipv6.at(i - 1).isEmpty())
       
   217                     return false;
       
   218                 addr[--mc] = 0;
       
   219                 addr[--mc] = 0;
       
   220             } else if (i == 0) {
       
   221                 // special case: ":" is first character
       
   222                 if (!ipv6.at(i + 1).isEmpty())
       
   223                     return false;
       
   224                 addr[--mc] = 0;
       
   225                 addr[--mc] = 0;
       
   226             } else {
       
   227                 for (int j = 0; j < fillCount; ++j) {
       
   228                     if (mc <= 0)
       
   229                         return false;
       
   230                     addr[--mc] = 0;
       
   231                     addr[--mc] = 0;
       
   232                 }
       
   233             }
       
   234         } else {
       
   235             bool ok = false;
       
   236             uint byteValue = ipv6.at(i).toUInt(&ok, 16);
       
   237             if (ok && byteValue <= 0xffff) {
       
   238                 addr[--mc] = byteValue & 0xff;
       
   239                 addr[--mc] = (byteValue >> 8) & 0xff;
       
   240             } else {
       
   241                 if (i != count - 1)
       
   242                     return false;
       
   243 
       
   244                 // parse the ipv4 part of a mixed type
       
   245                 quint32 maybeIp4;
       
   246                 if (!parseIp4(ipv6.at(i), &maybeIp4))
       
   247                     return false;
       
   248 
       
   249                 addr[--mc] = maybeIp4 & 0xff;
       
   250                 addr[--mc] = (maybeIp4 >> 8) & 0xff;
       
   251                 addr[--mc] = (maybeIp4 >> 16) & 0xff;
       
   252                 addr[--mc] = (maybeIp4 >> 24) & 0xff;
       
   253                 --fillCount;
       
   254             }
       
   255         }
       
   256     }
       
   257 
       
   258     return true;
       
   259 }
       
   260 
       
   261 bool QHostAddressPrivate::parse()
       
   262 {
       
   263     isParsed = true;
       
   264     protocol = QAbstractSocket::UnknownNetworkLayerProtocol;
       
   265     QString a = ipString.simplified();
       
   266 
       
   267     // All IPv6 addresses contain a ':', and may contain a '.'.
       
   268     if (a.contains(QLatin1Char(':'))) {
       
   269         quint8 maybeIp6[16];
       
   270         if (parseIp6(a, maybeIp6, &scopeId)) {
       
   271             setAddress(maybeIp6);
       
   272             protocol = QAbstractSocket::IPv6Protocol;
       
   273             return true;
       
   274         }
       
   275     }
       
   276 
       
   277     // All IPv4 addresses contain a '.'.
       
   278     if (a.contains(QLatin1Char('.'))) {
       
   279         quint32 maybeIp4 = 0;
       
   280         if (parseIp4(a, &maybeIp4)) {
       
   281             setAddress(maybeIp4);
       
   282             protocol = QAbstractSocket::IPv4Protocol;
       
   283             return true;
       
   284         }
       
   285     }
       
   286 
       
   287     return false;
       
   288 }
       
   289 
       
   290 void QHostAddressPrivate::clear()
       
   291 {
       
   292     a = 0;
       
   293     protocol = QAbstractSocket::UnknownNetworkLayerProtocol;
       
   294     isParsed = true;
       
   295     memset(&a6, 0, sizeof(a6));
       
   296 }
       
   297 
       
   298 
       
   299 bool QNetmaskAddress::setAddress(const QString &address)
       
   300 {
       
   301     length = -1;
       
   302     QHostAddress other;
       
   303     return other.setAddress(address) && setAddress(other);
       
   304 }
       
   305 
       
   306 bool QNetmaskAddress::setAddress(const QHostAddress &address)
       
   307 {
       
   308     static const quint8 zeroes[16] = { 0 };
       
   309     union {
       
   310         quint32 v4;
       
   311         quint8 v6[16];
       
   312     } ip;
       
   313 
       
   314     int netmask = 0;
       
   315     quint8 *ptr = ip.v6;
       
   316     quint8 *end;
       
   317     length = -1;
       
   318 
       
   319     QHostAddress::operator=(address);
       
   320 
       
   321     if (d->protocol == QAbstractSocket::IPv4Protocol) {
       
   322         ip.v4 = qToBigEndian(d->a);
       
   323         end = ptr + 4;
       
   324     } else if (d->protocol == QAbstractSocket::IPv6Protocol) {
       
   325         memcpy(ip.v6, d->a6.c, 16);
       
   326         end = ptr + 16;
       
   327     } else {
       
   328         d->clear();
       
   329         return false;
       
   330     }
       
   331 
       
   332     while (ptr < end) {
       
   333         switch (*ptr) {
       
   334         case 255:
       
   335             netmask += 8;
       
   336             ++ptr;
       
   337             continue;
       
   338 
       
   339         default:
       
   340             d->clear();
       
   341             return false;       // invalid IP-style netmask
       
   342 
       
   343             // the rest always falls through
       
   344         case 254:
       
   345             ++netmask;
       
   346         case 252:
       
   347             ++netmask;
       
   348         case 248:
       
   349             ++netmask;
       
   350         case 240:
       
   351             ++netmask;
       
   352         case 224:
       
   353             ++netmask;
       
   354         case 192:
       
   355             ++netmask;
       
   356         case 128:
       
   357             ++netmask;
       
   358         case 0:
       
   359             break;
       
   360         }
       
   361         break;
       
   362     }
       
   363 
       
   364     // confirm that the rest is only zeroes
       
   365     if (ptr < end && memcmp(ptr + 1, zeroes, end - ptr - 1) != 0) {
       
   366         d->clear();
       
   367         return false;
       
   368     }
       
   369 
       
   370     length = netmask;
       
   371     return true;
       
   372 }
       
   373 
       
   374 static void clearBits(quint8 *where, int start, int end)
       
   375 {
       
   376     Q_ASSERT(end == 32 || end == 128);
       
   377     if (start == end)
       
   378         return;
       
   379 
       
   380     // for the byte where 'start' is, clear the lower bits only
       
   381     quint8 bytemask = 256 - (1 << (8 - (start & 7)));
       
   382     where[start / 8] &= bytemask;
       
   383 
       
   384     // for the tail part, clear everything
       
   385     memset(where + (start + 7) / 8, 0, end / 8 - (start + 7) / 8);
       
   386 }
       
   387 
       
   388 int QNetmaskAddress::prefixLength() const
       
   389 {
       
   390     return length;
       
   391 }
       
   392 
       
   393 void QNetmaskAddress::setPrefixLength(QAbstractSocket::NetworkLayerProtocol proto, int newLength)
       
   394 {
       
   395     length = newLength;
       
   396     if (length < 0 || length > (proto == QAbstractSocket::IPv4Protocol ? 32 :
       
   397                                 proto == QAbstractSocket::IPv6Protocol ? 128 : -1)) {
       
   398         // invalid information, reject
       
   399         d->protocol = QAbstractSocket::UnknownNetworkLayerProtocol;
       
   400         length = -1;
       
   401         return;
       
   402     }
       
   403 
       
   404     d->protocol = proto;
       
   405     if (d->protocol == QAbstractSocket::IPv4Protocol) {
       
   406         if (length == 0) {
       
   407             d->a = 0;
       
   408         } else if (length == 32) {
       
   409             d->a = quint32(0xffffffff);
       
   410         } else {
       
   411             d->a = quint32(0xffffffff) >> (32 - length) << (32 - length);
       
   412         }
       
   413     } else {
       
   414         memset(d->a6.c, 0xFF, sizeof(d->a6));
       
   415         clearBits(d->a6.c, length, 128);
       
   416     }
       
   417 }
       
   418 
       
   419 /*!
       
   420     \class QHostAddress
       
   421     \brief The QHostAddress class provides an IP address.
       
   422     \ingroup network
       
   423     \inmodule QtNetwork
       
   424 
       
   425     This class holds an IPv4 or IPv6 address in a platform- and
       
   426     protocol-independent manner.
       
   427 
       
   428     QHostAddress is normally used with the QTcpSocket, QTcpServer,
       
   429     and QUdpSocket to connect to a host or to set up a server.
       
   430 
       
   431     A host address is set with setAddress(), checked for its type
       
   432     using isIPv4Address() or isIPv6Address(), and retrieved with
       
   433     toIPv4Address(), toIPv6Address(), or toString().
       
   434 
       
   435     \note Please note that QHostAddress does not do DNS lookups.
       
   436     QHostInfo is needed for that.
       
   437 
       
   438     The class also supports common predefined addresses: \l Null, \l
       
   439     LocalHost, \l LocalHostIPv6, \l Broadcast, and \l Any.
       
   440 
       
   441     \sa QHostInfo, QTcpSocket, QTcpServer, QUdpSocket
       
   442 */
       
   443 
       
   444 /*! \enum QHostAddress::SpecialAddress
       
   445 
       
   446     \value Null The null address object. Equivalent to QHostAddress().
       
   447     \value LocalHost The IPv4 localhost address. Equivalent to QHostAddress("127.0.0.1").
       
   448     \value LocalHostIPv6 The IPv6 localhost address. Equivalent to QHostAddress("::1").
       
   449     \value Broadcast The IPv4 broadcast address. Equivalent to QHostAddress("255.255.255.255").
       
   450     \value Any The IPv4 any-address. Equivalent to QHostAddress("0.0.0.0").
       
   451     \value AnyIPv6 The IPv6 any-address. Equivalent to QHostAddress("::").
       
   452 */
       
   453 
       
   454 /*!  Constructs a host address object with the IP address 0.0.0.0.
       
   455 
       
   456     \sa clear()
       
   457 */
       
   458 QHostAddress::QHostAddress()
       
   459     : d(new QHostAddressPrivate)
       
   460 {
       
   461 }
       
   462 
       
   463 /*!
       
   464     Constructs a host address object with the IPv4 address \a ip4Addr.
       
   465 */
       
   466 QHostAddress::QHostAddress(quint32 ip4Addr)
       
   467     : d(new QHostAddressPrivate)
       
   468 {
       
   469     setAddress(ip4Addr);
       
   470 }
       
   471 
       
   472 /*!
       
   473     Constructs a host address object with the IPv6 address \a ip6Addr.
       
   474 
       
   475     \a ip6Addr must be a 16-byte array in network byte order (big
       
   476     endian).
       
   477 */
       
   478 QHostAddress::QHostAddress(quint8 *ip6Addr)
       
   479     : d(new QHostAddressPrivate)
       
   480 {
       
   481     setAddress(ip6Addr);
       
   482 }
       
   483 
       
   484 /*!
       
   485     Constructs a host address object with the IPv6 address \a ip6Addr.
       
   486 */
       
   487 QHostAddress::QHostAddress(const Q_IPV6ADDR &ip6Addr)
       
   488     : d(new QHostAddressPrivate)
       
   489 {
       
   490     setAddress(ip6Addr);
       
   491 }
       
   492 
       
   493 /*!
       
   494     Constructs an IPv4 or IPv6 address based on the string \a address
       
   495     (e.g., "127.0.0.1").
       
   496 
       
   497     \sa setAddress()
       
   498 */
       
   499 QHostAddress::QHostAddress(const QString &address)
       
   500     : d(new QHostAddressPrivate)
       
   501 {
       
   502     d->ipString = address;
       
   503     d->isParsed = false;
       
   504 }
       
   505 
       
   506 /*!
       
   507     \fn QHostAddress::QHostAddress(const sockaddr *sockaddr)
       
   508 
       
   509     Constructs an IPv4 or IPv6 address using the address specified by
       
   510     the native structure \a sockaddr.
       
   511 
       
   512     \sa setAddress()
       
   513 */
       
   514 QHostAddress::QHostAddress(const struct sockaddr *sockaddr)
       
   515     : d(new QHostAddressPrivate)
       
   516 {
       
   517     if (sockaddr->sa_family == AF_INET)
       
   518         setAddress(htonl(((sockaddr_in *)sockaddr)->sin_addr.s_addr));
       
   519 #ifndef QT_NO_IPV6
       
   520     else if (sockaddr->sa_family == AF_INET6)
       
   521         setAddress(((qt_sockaddr_in6 *)sockaddr)->sin6_addr.qt_s6_addr);
       
   522 #endif
       
   523 }
       
   524 
       
   525 /*!
       
   526     Constructs a copy of the given \a address.
       
   527 */
       
   528 QHostAddress::QHostAddress(const QHostAddress &address)
       
   529     : d(new QHostAddressPrivate(*address.d.data()))
       
   530 {
       
   531 }
       
   532 
       
   533 /*!
       
   534     Constructs a QHostAddress object for \a address.
       
   535 */
       
   536 QHostAddress::QHostAddress(SpecialAddress address)
       
   537     : d(new QHostAddressPrivate)
       
   538 {
       
   539     switch (address) {
       
   540     case Null:
       
   541         break;
       
   542     case Broadcast:
       
   543         setAddress(QLatin1String("255.255.255.255"));
       
   544         break;
       
   545     case LocalHost:
       
   546         setAddress(QLatin1String("127.0.0.1"));
       
   547         break;
       
   548     case LocalHostIPv6:
       
   549         setAddress(QLatin1String("::1"));
       
   550         break;
       
   551     case Any:
       
   552         setAddress(QLatin1String("0.0.0.0"));
       
   553         break;
       
   554     case AnyIPv6:
       
   555         setAddress(QLatin1String("::"));
       
   556         break;
       
   557     }
       
   558 }
       
   559 
       
   560 /*!
       
   561     Destroys the host address object.
       
   562 */
       
   563 QHostAddress::~QHostAddress()
       
   564 {
       
   565 }
       
   566 
       
   567 /*!
       
   568     Assigns another host \a address to this object, and returns a reference
       
   569     to this object.
       
   570 */
       
   571 QHostAddress &QHostAddress::operator=(const QHostAddress &address)
       
   572 {
       
   573     *d.data() = *address.d.data();
       
   574     return *this;
       
   575 }
       
   576 
       
   577 /*!
       
   578     Assigns the host address \a address to this object, and returns a
       
   579     reference to this object.
       
   580 
       
   581     \sa setAddress()
       
   582 */
       
   583 QHostAddress &QHostAddress::operator=(const QString &address)
       
   584 {
       
   585     setAddress(address);
       
   586     return *this;
       
   587 }
       
   588 
       
   589 /*!
       
   590     \fn bool QHostAddress::operator!=(const QHostAddress &other) const
       
   591     \since 4.2
       
   592 
       
   593     Returns true if this host address is not the same as the \a other
       
   594     address given; otherwise returns false.
       
   595 */
       
   596 
       
   597 /*!
       
   598     \fn bool QHostAddress::operator!=(SpecialAddress other) const
       
   599 
       
   600     Returns true if this host address is not the same as the \a other
       
   601     address given; otherwise returns false.
       
   602 */
       
   603 
       
   604 /*!
       
   605     Sets the host address to 0.0.0.0.
       
   606 */
       
   607 void QHostAddress::clear()
       
   608 {
       
   609     d->clear();
       
   610 }
       
   611 
       
   612 /*!
       
   613     Set the IPv4 address specified by \a ip4Addr.
       
   614 */
       
   615 void QHostAddress::setAddress(quint32 ip4Addr)
       
   616 {
       
   617     d->setAddress(ip4Addr);
       
   618 }
       
   619 
       
   620 /*!
       
   621     \overload
       
   622 
       
   623     Set the IPv6 address specified by \a ip6Addr.
       
   624 
       
   625     \a ip6Addr must be an array of 16 bytes in network byte order
       
   626     (high-order byte first).
       
   627 */
       
   628 void QHostAddress::setAddress(quint8 *ip6Addr)
       
   629 {
       
   630     d->setAddress(ip6Addr);
       
   631 }
       
   632 
       
   633 /*!
       
   634     \overload
       
   635 
       
   636     Set the IPv6 address specified by \a ip6Addr.
       
   637 */
       
   638 void QHostAddress::setAddress(const Q_IPV6ADDR &ip6Addr)
       
   639 {
       
   640     d->setAddress(ip6Addr);
       
   641 }
       
   642 
       
   643 /*!
       
   644     \overload
       
   645 
       
   646     Sets the IPv4 or IPv6 address specified by the string
       
   647     representation specified by \a address (e.g. "127.0.0.1").
       
   648     Returns true and sets the address if the address was successfully
       
   649     parsed; otherwise returns false.
       
   650 */
       
   651 bool QHostAddress::setAddress(const QString &address)
       
   652 {
       
   653     d->ipString = address;
       
   654     return d->parse();
       
   655 }
       
   656 
       
   657 /*!
       
   658     \fn void QHostAddress::setAddress(const sockaddr *sockaddr)
       
   659     \overload
       
   660 
       
   661     Sets the IPv4 or IPv6 address specified by the native structure \a
       
   662     sockaddr.  Returns true and sets the address if the address was
       
   663     successfully parsed; otherwise returns false.
       
   664 */
       
   665 void QHostAddress::setAddress(const struct sockaddr *sockaddr)
       
   666 {
       
   667     clear();
       
   668     if (sockaddr->sa_family == AF_INET)
       
   669         setAddress(htonl(((sockaddr_in *)sockaddr)->sin_addr.s_addr));
       
   670 #ifndef QT_NO_IPV6
       
   671     else if (sockaddr->sa_family == AF_INET6)
       
   672         setAddress(((qt_sockaddr_in6 *)sockaddr)->sin6_addr.qt_s6_addr);
       
   673 #endif
       
   674 }
       
   675 
       
   676 /*!
       
   677     Returns the IPv4 address as a number.
       
   678 
       
   679     For example, if the address is 127.0.0.1, the returned value is
       
   680     2130706433 (i.e. 0x7f000001).
       
   681 
       
   682     This value is only valid if isIp4Addr() returns true.
       
   683 
       
   684     \sa toString()
       
   685 */
       
   686 quint32 QHostAddress::toIPv4Address() const
       
   687 {
       
   688     QT_ENSURE_PARSED(this);
       
   689     return d->a;
       
   690 }
       
   691 
       
   692 /*!
       
   693     Returns the network layer protocol of the host address.
       
   694 */
       
   695 QAbstractSocket::NetworkLayerProtocol QHostAddress::protocol() const
       
   696 {
       
   697     QT_ENSURE_PARSED(this);
       
   698     return d->protocol;
       
   699 }
       
   700 
       
   701 /*!
       
   702     Returns the IPv6 address as a Q_IPV6ADDR structure. The structure
       
   703     consists of 16 unsigned characters.
       
   704 
       
   705     \snippet doc/src/snippets/code/src_network_kernel_qhostaddress.cpp 0
       
   706 
       
   707     This value is only valid if isIPv6Address() returns true.
       
   708 
       
   709     \sa toString()
       
   710 */
       
   711 Q_IPV6ADDR QHostAddress::toIPv6Address() const
       
   712 {
       
   713     QT_ENSURE_PARSED(this);
       
   714     return d->a6;
       
   715 }
       
   716 
       
   717 /*!
       
   718     Returns the address as a string.
       
   719 
       
   720     For example, if the address is the IPv4 address 127.0.0.1, the
       
   721     returned string is "127.0.0.1".
       
   722 
       
   723     \sa toIPv4Address()
       
   724 */
       
   725 QString QHostAddress::toString() const
       
   726 {
       
   727     QT_ENSURE_PARSED(this);
       
   728     if (d->protocol == QAbstractSocket::IPv4Protocol) {
       
   729         quint32 i = toIPv4Address();
       
   730         QString s;
       
   731         s.sprintf("%d.%d.%d.%d", (i>>24) & 0xff, (i>>16) & 0xff,
       
   732                 (i >> 8) & 0xff, i & 0xff);
       
   733         return s;
       
   734     }
       
   735 
       
   736     if (d->protocol == QAbstractSocket::IPv6Protocol) {
       
   737         quint16 ugle[8];
       
   738         for (int i = 0; i < 8; i++) {
       
   739             ugle[i] = (quint16(d->a6[2*i]) << 8) | quint16(d->a6[2*i+1]);
       
   740         }
       
   741         QString s;
       
   742         s.sprintf("%X:%X:%X:%X:%X:%X:%X:%X",
       
   743                   ugle[0], ugle[1], ugle[2], ugle[3], ugle[4], ugle[5], ugle[6], ugle[7]);
       
   744         if (!d->scopeId.isEmpty())
       
   745             s.append(QLatin1Char('%') + d->scopeId);
       
   746         return s;
       
   747     }
       
   748 
       
   749     return QString();
       
   750 }
       
   751 
       
   752 /*!
       
   753     \since 4.1
       
   754 
       
   755     Returns the scope ID of an IPv6 address. For IPv4 addresses, or if the
       
   756     address does not contain a scope ID, an empty QString is returned.
       
   757 
       
   758     The IPv6 scope ID specifies the scope of \e reachability for non-global
       
   759     IPv6 addresses, limiting the area in which the address can be used. All
       
   760     IPv6 addresses are associated with such a reachability scope. The scope ID
       
   761     is used to disambiguate addresses that are not guaranteed to be globally
       
   762     unique.
       
   763 
       
   764     IPv6 specifies the following four levels of reachability:
       
   765 
       
   766     \list
       
   767 
       
   768     \o Node-local: Addresses that are only used for communicating with
       
   769     services on the same interface (e.g., the loopback interface "::1").
       
   770 
       
   771     \o Link-local: Addresses that are local to the network interface
       
   772     (\e{link}). There is always one link-local address for each IPv6 interface
       
   773     on your host. Link-local addresses ("fe80...") are generated from the MAC
       
   774     address of the local network adaptor, and are not guaranteed to be unique.
       
   775 
       
   776     \o Site-local: Addresses that are local to the site / private network
       
   777     (e.g., the company intranet). Site-local addresses ("fec0...")  are
       
   778     usually distributed by the site router, and are not guaranteed to be
       
   779     unique outside of the local site.
       
   780 
       
   781     \o Global: For globally routable addresses, such as public servers on the
       
   782     Internet.
       
   783 
       
   784     \endlist
       
   785 
       
   786     When using a link-local or site-local address for IPv6 connections, you
       
   787     must specify the scope ID. The scope ID for a link-local address is
       
   788     usually the same as the interface name (e.g., "eth0", "en1") or number
       
   789     (e.g., "1", "2").
       
   790 
       
   791     \sa setScopeId()
       
   792 */
       
   793 QString QHostAddress::scopeId() const
       
   794 {
       
   795     QT_ENSURE_PARSED(this);
       
   796     return (d->protocol == QAbstractSocket::IPv6Protocol) ? d->scopeId : QString();
       
   797 }
       
   798 
       
   799 /*!
       
   800     \since 4.1
       
   801 
       
   802     Sets the IPv6 scope ID of the address to \a id. If the address
       
   803     protocol is not IPv6, this function does nothing.
       
   804 */
       
   805 void QHostAddress::setScopeId(const QString &id)
       
   806 {
       
   807     QT_ENSURE_PARSED(this);
       
   808     if (d->protocol == QAbstractSocket::IPv6Protocol)
       
   809         d->scopeId = id;
       
   810 }
       
   811 
       
   812 /*!
       
   813     Returns true if this host address is the same as the \a other address
       
   814     given; otherwise returns false.
       
   815 */
       
   816 bool QHostAddress::operator==(const QHostAddress &other) const
       
   817 {
       
   818     QT_ENSURE_PARSED(this);
       
   819     QT_ENSURE_PARSED(&other);
       
   820 
       
   821     if (d->protocol == QAbstractSocket::IPv4Protocol)
       
   822         return other.d->protocol == QAbstractSocket::IPv4Protocol && d->a == other.d->a;
       
   823     if (d->protocol == QAbstractSocket::IPv6Protocol) {
       
   824         return other.d->protocol == QAbstractSocket::IPv6Protocol
       
   825                && memcmp(&d->a6, &other.d->a6, sizeof(Q_IPV6ADDR)) == 0;
       
   826     }
       
   827     return d->protocol == other.d->protocol;
       
   828 }
       
   829 
       
   830 /*!
       
   831     Returns true if this host address is the same as the \a other
       
   832     address given; otherwise returns false.
       
   833 */
       
   834 bool QHostAddress::operator ==(SpecialAddress other) const
       
   835 {
       
   836     QT_ENSURE_PARSED(this);
       
   837     QHostAddress otherAddress(other);
       
   838     QT_ENSURE_PARSED(&otherAddress);
       
   839 
       
   840     if (d->protocol == QAbstractSocket::IPv4Protocol)
       
   841         return otherAddress.d->protocol == QAbstractSocket::IPv4Protocol && d->a == otherAddress.d->a;
       
   842     if (d->protocol == QAbstractSocket::IPv6Protocol) {
       
   843         return otherAddress.d->protocol == QAbstractSocket::IPv6Protocol
       
   844                && memcmp(&d->a6, &otherAddress.d->a6, sizeof(Q_IPV6ADDR)) == 0;
       
   845     }
       
   846     return int(other) == int(Null);
       
   847 }
       
   848 
       
   849 /*!
       
   850     Returns true if this host address is null (INADDR_ANY or in6addr_any).
       
   851     The default constructor creates a null address, and that address is
       
   852     not valid for any host or interface.
       
   853 */
       
   854 bool QHostAddress::isNull() const
       
   855 {
       
   856     QT_ENSURE_PARSED(this);
       
   857     return d->protocol == QAbstractSocket::UnknownNetworkLayerProtocol;
       
   858 }
       
   859 
       
   860 /*!
       
   861     \fn quint32 QHostAddress::ip4Addr() const
       
   862 
       
   863     Use toIPv4Address() instead.
       
   864 */
       
   865 
       
   866 /*!
       
   867     \fn bool QHostAddress::isIp4Addr() const
       
   868 
       
   869     Use protocol() instead.
       
   870 */
       
   871 
       
   872 /*!
       
   873     \fn bool QHostAddress::isIPv4Address() const
       
   874 
       
   875     Use protocol() instead.
       
   876 */
       
   877 
       
   878 /*!
       
   879     \fn bool QHostAddress::isIPv6Address() const
       
   880 
       
   881     Use protocol() instead.
       
   882 */
       
   883 
       
   884 /*!
       
   885     \since 4.5
       
   886 
       
   887     Returns true if this IP is in the subnet described by the network
       
   888     prefix \a subnet and netmask \a netmask.
       
   889 
       
   890     An IP is considered to belong to a subnet if it is contained
       
   891     between the lowest and the highest address in that subnet. In the
       
   892     case of IP version 4, the lowest address is the network address,
       
   893     while the highest address is the broadcast address.
       
   894 
       
   895     The \a subnet argument does not have to be the actual network
       
   896     address (the lowest address in the subnet). It can be any valid IP
       
   897     belonging to that subnet. In particular, if it is equal to the IP
       
   898     address held by this object, this function will always return true
       
   899     (provided the netmask is a valid value).
       
   900 
       
   901     \sa parseSubnet()
       
   902 */
       
   903 bool QHostAddress::isInSubnet(const QHostAddress &subnet, int netmask) const
       
   904 {
       
   905     QT_ENSURE_PARSED(this);
       
   906     if (subnet.protocol() != d->protocol || netmask < 0)
       
   907         return false;
       
   908 
       
   909     union {
       
   910         quint32 ip;
       
   911         quint8 data[4];
       
   912     } ip4, net4;
       
   913     const quint8 *ip;
       
   914     const quint8 *net;
       
   915     if (d->protocol == QAbstractSocket::IPv4Protocol) {
       
   916         if (netmask > 32)
       
   917             netmask = 32;
       
   918         ip4.ip = qToBigEndian(d->a);
       
   919         net4.ip = qToBigEndian(subnet.d->a);
       
   920         ip = ip4.data;
       
   921         net = net4.data;
       
   922     } else if (d->protocol == QAbstractSocket::IPv6Protocol) {
       
   923         if (netmask > 128)
       
   924             netmask = 128;
       
   925         ip = d->a6.c;
       
   926         net = subnet.d->a6.c;
       
   927     } else {
       
   928         return false;
       
   929     }
       
   930 
       
   931     if (netmask >= 8 && memcmp(ip, net, netmask / 8) != 0)
       
   932         return false;
       
   933     if ((netmask & 7) == 0)
       
   934         return true;
       
   935 
       
   936     // compare the last octet now
       
   937     quint8 bytemask = 256 - (1 << (8 - (netmask & 7)));
       
   938     quint8 ipbyte = ip[netmask / 8];
       
   939     quint8 netbyte = net[netmask / 8];
       
   940     return (ipbyte & bytemask) == (netbyte & bytemask);
       
   941 }
       
   942 
       
   943 /*!
       
   944     \since 4.5
       
   945     \overload
       
   946 
       
   947     Returns true if this IP is in the subnet described by \a
       
   948     subnet. The QHostAddress member of \a subnet contains the network
       
   949     prefix and the int (second) member contains the netmask (prefix
       
   950     length).
       
   951 */
       
   952 bool QHostAddress::isInSubnet(const QPair<QHostAddress, int> &subnet) const
       
   953 {
       
   954     return isInSubnet(subnet.first, subnet.second);
       
   955 }
       
   956 
       
   957 
       
   958 /*!
       
   959     \since 4.5
       
   960 
       
   961     Parses the IP and subnet information contained in \a subnet and
       
   962     returns the network prefix for that network and its prefix length.
       
   963 
       
   964     The IP address and the netmask must be separated by a slash
       
   965     (/).
       
   966 
       
   967     This function supports arguments in the form:
       
   968     \list
       
   969       \o 123.123.123.123/n  where n is any value between 0 and 32
       
   970       \o 123.123.123.123/255.255.255.255
       
   971       \o <ipv6-address>/n  where n is any value between 0 and 128
       
   972     \endlist
       
   973 
       
   974     For IP version 4, this function accepts as well missing trailing
       
   975     components (i.e., less than 4 octets, like "192.168.1"), followed
       
   976     or not by a dot. If the netmask is also missing in that case, it
       
   977     is set to the number of octets actually passed (in the example
       
   978     above, it would be 24, for 3 octets).
       
   979 
       
   980     \sa isInSubnet()
       
   981 */
       
   982 QPair<QHostAddress, int> QHostAddress::parseSubnet(const QString &subnet)
       
   983 {
       
   984     // We support subnets in the form:
       
   985     //   ddd.ddd.ddd.ddd/nn
       
   986     //   ddd.ddd.ddd/nn
       
   987     //   ddd.ddd/nn
       
   988     //   ddd/nn
       
   989     //   ddd.ddd.ddd.
       
   990     //   ddd.ddd.ddd
       
   991     //   ddd.ddd.
       
   992     //   ddd.ddd
       
   993     //   ddd.
       
   994     //   ddd
       
   995     //   <ipv6-address>/nn
       
   996     //
       
   997     //  where nn can be an IPv4-style netmask for the IPv4 forms
       
   998 
       
   999     const QPair<QHostAddress, int> invalid = qMakePair(QHostAddress(), -1);
       
  1000     if (subnet.isEmpty())
       
  1001         return invalid;
       
  1002 
       
  1003     int slash = subnet.indexOf(QLatin1Char('/'));
       
  1004     QString netStr = subnet;
       
  1005     if (slash != -1)
       
  1006         netStr.truncate(slash);
       
  1007 
       
  1008     int netmask = -1;
       
  1009     bool isIpv6 = netStr.contains(QLatin1Char(':'));
       
  1010 
       
  1011     if (slash != -1) {
       
  1012         // is the netmask given in IP-form or in bit-count form?
       
  1013         if (!isIpv6 && subnet.indexOf(QLatin1Char('.'), slash + 1) != -1) {
       
  1014             // IP-style, convert it to bit-count form
       
  1015             QNetmaskAddress parser;
       
  1016             if (!parser.setAddress(subnet.mid(slash + 1)))
       
  1017                 return invalid;
       
  1018             netmask = parser.prefixLength();
       
  1019         } else {
       
  1020             bool ok;
       
  1021             netmask = subnet.mid(slash + 1).toUInt(&ok);
       
  1022             if (!ok)
       
  1023                 return invalid;     // failed to parse the subnet
       
  1024         }
       
  1025     }
       
  1026 
       
  1027     if (isIpv6) {
       
  1028         // looks like it's an IPv6 address
       
  1029         if (netmask > 128)
       
  1030             return invalid;     // invalid netmask
       
  1031         if (netmask < 0)
       
  1032             netmask = 128;
       
  1033 
       
  1034         QHostAddress net;
       
  1035         if (!net.setAddress(netStr))
       
  1036             return invalid;     // failed to parse the IP
       
  1037 
       
  1038         clearBits(net.d->a6.c, netmask, 128);
       
  1039         return qMakePair(net, netmask);
       
  1040     }
       
  1041 
       
  1042     if (netmask > 32)
       
  1043         return invalid;         // invalid netmask
       
  1044 
       
  1045     // parse the address manually
       
  1046     QStringList parts = netStr.split(QLatin1Char('.'));
       
  1047     if (parts.isEmpty() || parts.count() > 4)
       
  1048         return invalid;         // invalid IPv4 address
       
  1049 
       
  1050     if (parts.last().isEmpty())
       
  1051         parts.removeLast();
       
  1052 
       
  1053     quint32 addr = 0;
       
  1054     for (int i = 0; i < parts.count(); ++i) {
       
  1055         bool ok;
       
  1056         uint byteValue = parts.at(i).toUInt(&ok);
       
  1057         if (!ok || byteValue > 255)
       
  1058             return invalid;     // invalid IPv4 address
       
  1059 
       
  1060         addr <<= 8;
       
  1061         addr += byteValue;
       
  1062     }
       
  1063     addr <<= 8 * (4 - parts.count());
       
  1064     if (netmask == -1) {
       
  1065         netmask = 8 * parts.count();
       
  1066     } else if (netmask == 0) {
       
  1067         // special case here
       
  1068         // x86's instructions "shr" and "shl" do not operate when
       
  1069         // their argument is 32, so the code below doesn't work as expected
       
  1070         addr = 0;
       
  1071     } else if (netmask != 32) {
       
  1072         // clear remaining bits
       
  1073         quint32 mask = quint32(0xffffffff) >> (32 - netmask) << (32 - netmask);
       
  1074         addr &= mask;
       
  1075     }
       
  1076 
       
  1077     return qMakePair(QHostAddress(addr), netmask);
       
  1078 }
       
  1079 
       
  1080 #ifndef QT_NO_DEBUG_STREAM
       
  1081 QDebug operator<<(QDebug d, const QHostAddress &address)
       
  1082 {
       
  1083     d.maybeSpace() << "QHostAddress(" << address.toString() << ')';
       
  1084     return d.space();
       
  1085 }
       
  1086 #endif
       
  1087 
       
  1088 uint qHash(const QHostAddress &key)
       
  1089 {
       
  1090     return qHash(key.toString());
       
  1091 }
       
  1092 
       
  1093 #ifndef QT_NO_DATASTREAM
       
  1094 
       
  1095 /*! \relates QHostAddress
       
  1096 
       
  1097     Writes host address \a address to the stream \a out and returns a reference
       
  1098     to the stream.
       
  1099 
       
  1100     \sa {Format of the QDataStream operators}
       
  1101 */
       
  1102 QDataStream &operator<<(QDataStream &out, const QHostAddress &address)
       
  1103 {
       
  1104     qint8 prot;
       
  1105     prot = qint8(address.protocol());
       
  1106     out << prot;
       
  1107     switch (address.protocol()) {
       
  1108     case QAbstractSocket::UnknownNetworkLayerProtocol:
       
  1109         break;
       
  1110     case QAbstractSocket::IPv4Protocol:
       
  1111         out << address.toIPv4Address();
       
  1112         break;
       
  1113     case QAbstractSocket::IPv6Protocol:
       
  1114     {
       
  1115         Q_IPV6ADDR ipv6 = address.toIPv6Address();
       
  1116         for (int i = 0; i < 16; ++i)
       
  1117             out << ipv6[i];
       
  1118         out << address.scopeId();
       
  1119     }
       
  1120         break;
       
  1121     }
       
  1122     return out;
       
  1123 }
       
  1124 
       
  1125 /*! \relates QHostAddress
       
  1126 
       
  1127     Reads a host address into \a address from the stream \a in and returns a
       
  1128     reference to the stream.
       
  1129 
       
  1130     \sa {Format of the QDataStream operators}
       
  1131 */
       
  1132 QDataStream &operator>>(QDataStream &in, QHostAddress &address)
       
  1133 {
       
  1134     qint8 prot;
       
  1135     in >> prot;
       
  1136     switch (QAbstractSocket::NetworkLayerProtocol(prot)) {
       
  1137     case QAbstractSocket::UnknownNetworkLayerProtocol:
       
  1138         address.clear();
       
  1139         break;
       
  1140     case QAbstractSocket::IPv4Protocol:
       
  1141     {
       
  1142         quint32 ipv4;
       
  1143         in >> ipv4;
       
  1144         address.setAddress(ipv4);
       
  1145     }
       
  1146         break;
       
  1147     case QAbstractSocket::IPv6Protocol:
       
  1148     {
       
  1149         Q_IPV6ADDR ipv6;
       
  1150         for (int i = 0; i < 16; ++i)
       
  1151             in >> ipv6[i];
       
  1152         address.setAddress(ipv6);
       
  1153 
       
  1154         QString scope;
       
  1155         in >> scope;
       
  1156         address.setScopeId(scope);
       
  1157     }
       
  1158         break;
       
  1159     default:
       
  1160         address.clear();
       
  1161         in.setStatus(QDataStream::ReadCorruptData);
       
  1162     }
       
  1163     return in;
       
  1164 }
       
  1165 
       
  1166 #endif //QT_NO_DATASTREAM
       
  1167 
       
  1168 QT_END_NAMESPACE