util/src/network/kernel/qnetworkinterface.cpp
changeset 7 f7bc934e204c
equal deleted inserted replaced
3:41300fa6a67c 7:f7bc934e204c
       
     1 /****************************************************************************
       
     2 **
       
     3 ** Copyright (C) 2010 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 "qnetworkinterface.h"
       
    43 #include "qnetworkinterface_p.h"
       
    44 
       
    45 #include "qdebug.h"
       
    46 #include "qendian.h"
       
    47 
       
    48 #ifndef QT_NO_NETWORKINTERFACE
       
    49 
       
    50 QT_BEGIN_NAMESPACE
       
    51 
       
    52 static QList<QNetworkInterfacePrivate *> postProcess(QList<QNetworkInterfacePrivate *> list)
       
    53 {
       
    54     // Some platforms report a netmask but don't report a broadcast address
       
    55     // Go through all available addresses and calculate the broadcast address
       
    56     // from the IP and the netmask
       
    57     //
       
    58     // This is an IPv4-only thing -- IPv6 has no concept of broadcasts
       
    59     // The math is:
       
    60     //    broadcast = IP | ~netmask
       
    61 
       
    62     QList<QNetworkInterfacePrivate *>::Iterator it = list.begin();
       
    63     const QList<QNetworkInterfacePrivate *>::Iterator end = list.end();
       
    64     for ( ; it != end; ++it) {
       
    65         QList<QNetworkAddressEntry>::Iterator addr_it = (*it)->addressEntries.begin();
       
    66         const QList<QNetworkAddressEntry>::Iterator addr_end = (*it)->addressEntries.end();
       
    67         for ( ; addr_it != addr_end; ++addr_it) {
       
    68             if (addr_it->ip().protocol() != QAbstractSocket::IPv4Protocol)
       
    69                 continue;
       
    70 
       
    71             if (!addr_it->netmask().isNull() && addr_it->broadcast().isNull()) {
       
    72                 QHostAddress bcast = addr_it->ip();
       
    73                 bcast = QHostAddress(bcast.toIPv4Address() | ~addr_it->netmask().toIPv4Address());
       
    74                 addr_it->setBroadcast(bcast);
       
    75             }
       
    76         }
       
    77     }
       
    78 
       
    79     return list;
       
    80 }
       
    81 
       
    82 Q_GLOBAL_STATIC(QNetworkInterfaceManager, manager)
       
    83 
       
    84 QNetworkInterfaceManager::QNetworkInterfaceManager()
       
    85 {
       
    86 }
       
    87 
       
    88 QNetworkInterfaceManager::~QNetworkInterfaceManager()
       
    89 {
       
    90 }
       
    91 
       
    92 QSharedDataPointer<QNetworkInterfacePrivate> QNetworkInterfaceManager::interfaceFromName(const QString &name)
       
    93 {
       
    94     QList<QSharedDataPointer<QNetworkInterfacePrivate> > interfaceList = allInterfaces();
       
    95     QList<QSharedDataPointer<QNetworkInterfacePrivate> >::ConstIterator it = interfaceList.constBegin();
       
    96     for ( ; it != interfaceList.constEnd(); ++it)
       
    97         if ((*it)->name == name)
       
    98             return *it;
       
    99 
       
   100     return empty;
       
   101 }
       
   102 
       
   103 QSharedDataPointer<QNetworkInterfacePrivate> QNetworkInterfaceManager::interfaceFromIndex(int index)
       
   104 {
       
   105     QList<QSharedDataPointer<QNetworkInterfacePrivate> > interfaceList = allInterfaces();
       
   106     QList<QSharedDataPointer<QNetworkInterfacePrivate> >::ConstIterator it = interfaceList.constBegin();
       
   107     for ( ; it != interfaceList.constEnd(); ++it)
       
   108         if ((*it)->index == index)
       
   109             return *it;
       
   110 
       
   111     return empty;
       
   112 }
       
   113 
       
   114 QList<QSharedDataPointer<QNetworkInterfacePrivate> > QNetworkInterfaceManager::allInterfaces()
       
   115 {
       
   116     QList<QNetworkInterfacePrivate *> list = postProcess(scan());
       
   117     QList<QSharedDataPointer<QNetworkInterfacePrivate> > result;
       
   118 
       
   119     foreach (QNetworkInterfacePrivate *ptr, list)
       
   120         result << QSharedDataPointer<QNetworkInterfacePrivate>(ptr);
       
   121 
       
   122     return result;
       
   123 }
       
   124 
       
   125 QString QNetworkInterfacePrivate::makeHwAddress(int len, uchar *data)
       
   126 {
       
   127     QString result;
       
   128     for (int i = 0; i < len; ++i) {
       
   129         if (i)
       
   130             result += QLatin1Char(':');
       
   131 
       
   132         char buf[3];
       
   133 #if defined(Q_OS_WIN) && !defined(Q_OS_WINCE) && defined(_MSC_VER) && _MSC_VER >= 1400
       
   134         sprintf_s(buf, 3, "%02hX", ushort(data[i]));
       
   135 #else
       
   136         sprintf(buf, "%02hX", ushort(data[i]));
       
   137 #endif
       
   138         result += QLatin1String(buf);
       
   139     }
       
   140     return result;
       
   141 }
       
   142 
       
   143 /*!
       
   144     \class QNetworkAddressEntry
       
   145     \brief The QNetworkAddressEntry class stores one IP address
       
   146     supported by a network interface, along with its associated
       
   147     netmask and broadcast address.
       
   148 
       
   149     \since 4.2
       
   150     \reentrant
       
   151     \ingroup network
       
   152 
       
   153     Each network interface can contain zero or more IP addresses, which
       
   154     in turn can be associated with a netmask and/or a broadcast
       
   155     address (depending on support from the operating system).
       
   156 
       
   157     This class represents one such group.
       
   158 */
       
   159 
       
   160 /*!
       
   161     Constructs an empty QNetworkAddressEntry object.
       
   162 */
       
   163 QNetworkAddressEntry::QNetworkAddressEntry()
       
   164     : d(new QNetworkAddressEntryPrivate)
       
   165 {
       
   166 }
       
   167 
       
   168 /*!
       
   169     Constructs a QNetworkAddressEntry object that is a copy of the
       
   170     object \a other.
       
   171 */
       
   172 QNetworkAddressEntry::QNetworkAddressEntry(const QNetworkAddressEntry &other)
       
   173     : d(new QNetworkAddressEntryPrivate(*other.d.data()))
       
   174 {
       
   175 }
       
   176 
       
   177 /*!
       
   178     Makes a copy of the QNetworkAddressEntry object \a other.
       
   179 */
       
   180 QNetworkAddressEntry &QNetworkAddressEntry::operator=(const QNetworkAddressEntry &other)
       
   181 {
       
   182     *d.data() = *other.d.data();
       
   183     return *this;
       
   184 }
       
   185 
       
   186 /*!
       
   187     Destroys this QNetworkAddressEntry object.
       
   188 */
       
   189 QNetworkAddressEntry::~QNetworkAddressEntry()
       
   190 {
       
   191 }
       
   192 
       
   193 /*!
       
   194     Returns true if this network address entry is the same as \a
       
   195     other.
       
   196 */
       
   197 bool QNetworkAddressEntry::operator==(const QNetworkAddressEntry &other) const
       
   198 {
       
   199     if (d == other.d) return true;
       
   200     if (!d || !other.d) return false;
       
   201     return d->address == other.d->address &&
       
   202         d->netmask == other.d->netmask &&
       
   203         d->broadcast == other.d->broadcast;
       
   204 }
       
   205 
       
   206 /*!
       
   207     \fn bool QNetworkAddressEntry::operator!=(const QNetworkAddressEntry &other) const
       
   208 
       
   209     Returns true if this network address entry is different from \a
       
   210     other.
       
   211 */
       
   212 
       
   213 /*!
       
   214     This function returns one IPv4 or IPv6 address found, that was
       
   215     found in a network interface.
       
   216 */
       
   217 QHostAddress QNetworkAddressEntry::ip() const
       
   218 {
       
   219     return d->address;
       
   220 }
       
   221 
       
   222 /*!
       
   223     Sets the IP address the QNetworkAddressEntry object contains to \a
       
   224     newIp.
       
   225 */
       
   226 void QNetworkAddressEntry::setIp(const QHostAddress &newIp)
       
   227 {
       
   228     d->address = newIp;
       
   229 }
       
   230 
       
   231 /*!
       
   232     Returns the netmask associated with the IP address. The
       
   233     netmask is expressed in the form of an IP address, such as
       
   234     255.255.0.0.
       
   235 
       
   236     For IPv6 addresses, the prefix length is converted to an address
       
   237     where the number of bits set to 1 is equal to the prefix
       
   238     length. For a prefix length of 64 bits (the most common value),
       
   239     the netmask will be expressed as a QHostAddress holding the
       
   240     address FFFF:FFFF:FFFF:FFFF::
       
   241 
       
   242     \sa prefixLength()
       
   243 */
       
   244 QHostAddress QNetworkAddressEntry::netmask() const
       
   245 {
       
   246     return d->netmask;
       
   247 }
       
   248 
       
   249 /*!
       
   250     Sets the netmask that this QNetworkAddressEntry object contains to
       
   251     \a newNetmask. Setting the netmask also sets the prefix length to
       
   252     match the new netmask.
       
   253 
       
   254     \sa setPrefixLength()
       
   255 */
       
   256 void QNetworkAddressEntry::setNetmask(const QHostAddress &newNetmask)
       
   257 {
       
   258     if (newNetmask.protocol() != ip().protocol()) {
       
   259         d->netmask = QNetmaskAddress();
       
   260         return;
       
   261     }
       
   262 
       
   263     d->netmask.setAddress(newNetmask);
       
   264 }
       
   265 
       
   266 /*!
       
   267     \since 4.5
       
   268     Returns the prefix length of this IP address. The prefix length
       
   269     matches the number of bits set to 1 in the netmask (see
       
   270     netmask()). For IPv4 addresses, the value is between 0 and 32. For
       
   271     IPv6 addresses, it's contained between 0 and 128 and is the
       
   272     preferred form of representing addresses.
       
   273 
       
   274     This function returns -1 if the prefix length could not be
       
   275     determined (i.e., netmask() returns a null QHostAddress()).
       
   276 
       
   277     \sa netmask()
       
   278 */
       
   279 int QNetworkAddressEntry::prefixLength() const
       
   280 {
       
   281     return d->netmask.prefixLength();
       
   282 }
       
   283 
       
   284 /*!
       
   285     \since 4.5
       
   286     Sets the prefix length of this IP address to \a length. The value
       
   287     of \a length must be valid for this type of IP address: between 0
       
   288     and 32 for IPv4 addresses, between 0 and 128 for IPv6
       
   289     addresses. Setting to any invalid value is equivalent to setting
       
   290     to -1, which means "no prefix length".
       
   291 
       
   292     Setting the prefix length also sets the netmask (see netmask()).
       
   293 
       
   294     \sa setNetmask()
       
   295 */
       
   296 void QNetworkAddressEntry::setPrefixLength(int length)
       
   297 {
       
   298     d->netmask.setPrefixLength(d->address.protocol(), length);
       
   299 }
       
   300 
       
   301 /*!
       
   302     Returns the broadcast address associated with the IPv4
       
   303     address and netmask. It can usually be derived from those two by
       
   304     setting to 1 the bits of the IP address where the netmask contains
       
   305     a 0. (In other words, by bitwise-OR'ing the IP address with the
       
   306     inverse of the netmask)
       
   307 
       
   308     This member is always empty for IPv6 addresses, since the concept
       
   309     of broadcast has been abandoned in that system in favor of
       
   310     multicast. In particular, the group of hosts corresponding to all
       
   311     the nodes in the local network can be reached by the "all-nodes"
       
   312     special multicast group (address FF02::1).
       
   313 */
       
   314 QHostAddress QNetworkAddressEntry::broadcast() const
       
   315 {
       
   316     return d->broadcast;
       
   317 }
       
   318 
       
   319 /*!
       
   320     Sets the broadcast IP address of this QNetworkAddressEntry object
       
   321     to \a newBroadcast.
       
   322 */
       
   323 void QNetworkAddressEntry::setBroadcast(const QHostAddress &newBroadcast)
       
   324 {
       
   325     d->broadcast = newBroadcast;
       
   326 }
       
   327 
       
   328 /*!
       
   329     \class QNetworkInterface
       
   330     \brief The QNetworkInterface class provides a listing of the host's IP
       
   331     addresses and network interfaces.
       
   332 
       
   333     \since 4.2
       
   334     \reentrant
       
   335     \ingroup network
       
   336 
       
   337     QNetworkInterface represents one network interface attached to the
       
   338     host where the program is being run. Each network interface may
       
   339     contain zero or more IP addresses, each of which is optionally
       
   340     associated with a netmask and/or a broadcast address. The list of
       
   341     such trios can be obtained with addressEntries(). Alternatively,
       
   342     when the netmask or the broadcast addresses aren't necessary, use
       
   343     the allAddresses() convenience function to obtain just the IP
       
   344     addresses.
       
   345 
       
   346     QNetworkInterface also reports the interface's hardware address with
       
   347     hardwareAddress().
       
   348 
       
   349     Not all operating systems support reporting all features. Only the
       
   350     IPv4 addresses are guaranteed to be listed by this class in all
       
   351     platforms. In particular, IPv6 address listing is only supported
       
   352     on Windows XP and more recent versions, Linux, MacOS X and the
       
   353     BSDs.
       
   354 
       
   355     \sa QNetworkAddressEntry
       
   356 */
       
   357 
       
   358 /*!
       
   359     \enum QNetworkInterface::InterfaceFlag
       
   360     Specifies the flags associated with this network interface. The
       
   361     possible values are:
       
   362 
       
   363     \value IsUp                 the network interface is active
       
   364     \value IsRunning            the network interface has resources
       
   365                                 allocated
       
   366     \value CanBroadcast         the network interface works in
       
   367                                 broadcast mode
       
   368     \value IsLoopBack           the network interface is a loopback
       
   369                                 interface: that is, it's a virtual
       
   370                                 interface whose destination is the
       
   371                                 host computer itself
       
   372     \value IsPointToPoint       the network interface is a
       
   373                                 point-to-point interface: that is,
       
   374                                 there is one, single other address
       
   375                                 that can be directly reached by it.
       
   376     \value CanMulticast         the network interface supports
       
   377                                 multicasting
       
   378 
       
   379     Note that one network interface cannot be both broadcast-based and
       
   380     point-to-point.
       
   381 */
       
   382 
       
   383 /*!
       
   384     Constructs an empty network interface object.
       
   385 */
       
   386 QNetworkInterface::QNetworkInterface()
       
   387     : d(0)
       
   388 {
       
   389 }
       
   390 
       
   391 /*!
       
   392     Frees the resources associated with the QNetworkInterface object.
       
   393 */
       
   394 QNetworkInterface::~QNetworkInterface()
       
   395 {
       
   396 }
       
   397 
       
   398 /*!
       
   399     Creates a copy of the QNetworkInterface object contained in \a
       
   400     other.
       
   401 */
       
   402 QNetworkInterface::QNetworkInterface(const QNetworkInterface &other)
       
   403     : d(other.d)
       
   404 {
       
   405 }
       
   406 
       
   407 /*!
       
   408     Copies the contents of the QNetworkInterface object contained in \a
       
   409     other into this one.
       
   410 */
       
   411 QNetworkInterface &QNetworkInterface::operator=(const QNetworkInterface &other)
       
   412 {
       
   413     d = other.d;
       
   414     return *this;
       
   415 }
       
   416 
       
   417 /*!
       
   418     Returns true if this QNetworkInterface object contains valid
       
   419     information about a network interface.
       
   420 */
       
   421 bool QNetworkInterface::isValid() const
       
   422 {
       
   423     return !name().isEmpty();
       
   424 }
       
   425 
       
   426 /*!
       
   427     \since 4.5
       
   428     Returns the interface system index, if known. This is an integer
       
   429     assigned by the operating system to identify this interface and it
       
   430     generally doesn't change. It matches the scope ID field in IPv6
       
   431     addresses.
       
   432 
       
   433     If the index isn't known, this function returns 0.
       
   434 */
       
   435 int QNetworkInterface::index() const
       
   436 {
       
   437     return d ? d->index : 0;
       
   438 }
       
   439 
       
   440 /*!
       
   441     Returns the name of this network interface. On Unix systems, this
       
   442     is a string containing the type of the interface and optionally a
       
   443     sequence number, such as "eth0", "lo" or "pcn0". On Windows, it's
       
   444     an internal ID that cannot be changed by the user.
       
   445 */
       
   446 QString QNetworkInterface::name() const
       
   447 {
       
   448     return d ? d->name : QString();
       
   449 }
       
   450 
       
   451 /*!
       
   452     \since 4.5
       
   453 
       
   454     Returns the human-readable name of this network interface on
       
   455     Windows, such as "Local Area Connection", if the name could be
       
   456     determined. If it couldn't, this function returns the same as
       
   457     name(). The human-readable name is a name that the user can modify
       
   458     in the Windows Control Panel, so it may change during the
       
   459     execution of the program.
       
   460 
       
   461     On Unix, this function currently always returns the same as
       
   462     name(), since Unix systems don't store a configuration for
       
   463     human-readable names.
       
   464 */
       
   465 QString QNetworkInterface::humanReadableName() const
       
   466 {
       
   467     return d ? !d->friendlyName.isEmpty() ? d->friendlyName : name() : QString();
       
   468 }
       
   469 
       
   470 /*!
       
   471     Returns the flags associated with this network interface.
       
   472 */
       
   473 QNetworkInterface::InterfaceFlags QNetworkInterface::flags() const
       
   474 {
       
   475     return d ? d->flags : InterfaceFlags(0);
       
   476 }
       
   477 
       
   478 /*!
       
   479     Returns the low-level hardware address for this interface. On
       
   480     Ethernet interfaces, this will be a MAC address in string
       
   481     representation, separated by colons.
       
   482 
       
   483     Other interface types may have other types of hardware
       
   484     addresses. Implementations should not depend on this function
       
   485     returning a valid MAC address.
       
   486 */
       
   487 QString QNetworkInterface::hardwareAddress() const
       
   488 {
       
   489     return d ? d->hardwareAddress : QString();
       
   490 }
       
   491 
       
   492 /*!
       
   493     Returns the list of IP addresses that this interface possesses
       
   494     along with their associated netmasks and broadcast addresses.
       
   495 
       
   496     If the netmask or broadcast address information is not necessary,
       
   497     you can call the allAddresses() function to obtain just the IP
       
   498     addresses.
       
   499 */
       
   500 QList<QNetworkAddressEntry> QNetworkInterface::addressEntries() const
       
   501 {
       
   502     return d ? d->addressEntries : QList<QNetworkAddressEntry>();
       
   503 }
       
   504 
       
   505 /*!
       
   506     Returns a QNetworkInterface object for the interface named \a
       
   507     name. If no such interface exists, this function returns an
       
   508     invalid QNetworkInterface object.
       
   509 
       
   510     \sa name(), isValid()
       
   511 */
       
   512 QNetworkInterface QNetworkInterface::interfaceFromName(const QString &name)
       
   513 {
       
   514     QNetworkInterface result;
       
   515     result.d = manager()->interfaceFromName(name);
       
   516     return result;
       
   517 }
       
   518 
       
   519 /*!
       
   520     Returns a QNetworkInterface object for the interface whose internal
       
   521     ID is \a index. Network interfaces have a unique identifier called
       
   522     the "interface index" to distinguish it from other interfaces on
       
   523     the system. Often, this value is assigned progressively and
       
   524     interfaces being removed and then added again get a different
       
   525     value every time.
       
   526 
       
   527     This index is also found in the IPv6 address' scope ID field.
       
   528 */
       
   529 QNetworkInterface QNetworkInterface::interfaceFromIndex(int index)
       
   530 {
       
   531     QNetworkInterface result;
       
   532     result.d = manager()->interfaceFromIndex(index);
       
   533     return result;
       
   534 }
       
   535 
       
   536 /*!
       
   537     Returns a listing of all the network interfaces found on the host
       
   538     machine.
       
   539 */
       
   540 QList<QNetworkInterface> QNetworkInterface::allInterfaces()
       
   541 {
       
   542     QList<QSharedDataPointer<QNetworkInterfacePrivate> > privs = manager()->allInterfaces();
       
   543     QList<QNetworkInterface> result;
       
   544     foreach (const QSharedDataPointer<QNetworkInterfacePrivate> &p, privs) {
       
   545         QNetworkInterface item;
       
   546         item.d = p;
       
   547         result << item;
       
   548     }
       
   549 
       
   550     return result;
       
   551 }
       
   552 
       
   553 /*!
       
   554     This convenience function returns all IP addresses found on the
       
   555     host machine. It is equivalent to calling addressEntries() on all the
       
   556     objects returned by allInterfaces() to obtain lists of QHostAddress
       
   557     objects then calling QHostAddress::ip() on each of these.
       
   558 */
       
   559 QList<QHostAddress> QNetworkInterface::allAddresses()
       
   560 {
       
   561     QList<QSharedDataPointer<QNetworkInterfacePrivate> > privs = manager()->allInterfaces();
       
   562     QList<QHostAddress> result;
       
   563     foreach (const QSharedDataPointer<QNetworkInterfacePrivate> &p, privs) {
       
   564         foreach (const QNetworkAddressEntry &entry, p->addressEntries)
       
   565             result += entry.ip();
       
   566     }
       
   567 
       
   568     return result;
       
   569 }
       
   570 
       
   571 #ifndef QT_NO_DEBUG_STREAM
       
   572 static inline QDebug flagsDebug(QDebug debug, QNetworkInterface::InterfaceFlags flags)
       
   573 {
       
   574     if (flags & QNetworkInterface::IsUp)
       
   575         debug.nospace() << "IsUp ";
       
   576     if (flags & QNetworkInterface::IsRunning)
       
   577         debug.nospace() << "IsRunning ";
       
   578     if (flags & QNetworkInterface::CanBroadcast)
       
   579         debug.nospace() << "CanBroadcast ";
       
   580     if (flags & QNetworkInterface::IsLoopBack)
       
   581         debug.nospace() << "IsLoopBack ";
       
   582     if (flags & QNetworkInterface::IsPointToPoint)
       
   583         debug.nospace() << "IsPointToPoint ";
       
   584     if (flags & QNetworkInterface::CanMulticast)
       
   585         debug.nospace() << "CanMulticast ";
       
   586     return debug.nospace();
       
   587 }
       
   588 
       
   589 static inline QDebug operator<<(QDebug debug, const QNetworkAddressEntry &entry)
       
   590 {
       
   591     debug.nospace() << "(address = " << entry.ip();
       
   592     if (!entry.netmask().isNull())
       
   593         debug.nospace() << ", netmask = " << entry.netmask();
       
   594     if (!entry.broadcast().isNull())
       
   595         debug.nospace() << ", broadcast = " << entry.broadcast();
       
   596     debug.nospace() << ')';
       
   597     return debug.space();
       
   598 }
       
   599 
       
   600 QDebug operator<<(QDebug debug, const QNetworkInterface &networkInterface)
       
   601 {
       
   602     debug.nospace() << "QNetworkInterface(name = " << networkInterface.name()
       
   603                     << ", hardware address = " << networkInterface.hardwareAddress()
       
   604                     << ", flags = ";
       
   605     flagsDebug(debug, networkInterface.flags());
       
   606 #if defined(Q_CC_RVCT)
       
   607     // RVCT gets confused with << networkInterface.addressEntries(), reason unknown.
       
   608     debug.nospace() << ")\n";
       
   609 #else
       
   610     debug.nospace() << ", entries = " << networkInterface.addressEntries()
       
   611                     << ")\n";
       
   612 #endif
       
   613     return debug.space();
       
   614 }
       
   615 #endif
       
   616 
       
   617 QT_END_NAMESPACE
       
   618 
       
   619 #endif // QT_NO_NETWORKINTERFACE