From bcb704366cb5e333a626c18c308c7e0448a8e69f Mon Sep 17 00:00:00 2001 From: toma Date: Wed, 25 Nov 2009 17:56:58 +0000 Subject: Copy the KDE 3.5 branch to branches/trinity for new KDE 3.5 features. BUG:215923 git-svn-id: svn://anonsvn.kde.org/home/kde/branches/trinity/kdenetwork@1054174 283d02a7-25f6-0310-bc7c-ecb5cbfe19da --- krfb/srvloc/kinetinterface.cpp | 277 +++++++++++++++++++++++++++++++++++++++++ 1 file changed, 277 insertions(+) create mode 100644 krfb/srvloc/kinetinterface.cpp (limited to 'krfb/srvloc/kinetinterface.cpp') diff --git a/krfb/srvloc/kinetinterface.cpp b/krfb/srvloc/kinetinterface.cpp new file mode 100644 index 00000000..7ba5c15b --- /dev/null +++ b/krfb/srvloc/kinetinterface.cpp @@ -0,0 +1,277 @@ +/* + * Represents an Inet interface + * Copyright (C) 2002 Tim Jansen + * + * $Id$ + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Library General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Library General Public License for more details. + * + * You should have received a copy of the GNU Library General Public License + * along with this library; see the file COPYING.LIB. If not, write to + * the Free Software Foundation, Inc., 59 Temple Place - Suite 330, + * Boston, MA 02111-1307, USA. + */ + +#include "kinetinterface.h" + +#include "getifaddrs.h" + +#include +#include + + +class KInetInterfacePrivate { +public: + QString name; + int flags; + KInetSocketAddress *address; + KInetSocketAddress *netmask; + KInetSocketAddress *broadcast; + KInetSocketAddress *destination; + + KInetInterfacePrivate() : + flags(0), + address(0), + netmask(0), + broadcast(0), + destination(0) { + } + + KInetInterfacePrivate(const QString _name, + int _flags, + KInetSocketAddress *_address, + KInetSocketAddress *_netmask, + KInetSocketAddress *_broadcast, + KInetSocketAddress *_destination) : + name(_name), + flags(_flags), + address(_address), + netmask(_netmask), + broadcast(_broadcast), + destination(_destination) { + } + + ~KInetInterfacePrivate() { + if (address) + delete address; + if (netmask) + delete netmask; + if (broadcast) + delete broadcast; + if (destination) + delete destination; + } + + KInetInterfacePrivate& operator =(const KInetInterfacePrivate& i) { + name = i.name; + flags = i.flags; + if (i.address) + address = new KInetSocketAddress(*i.address); + else + address = 0; + if (i.netmask) + netmask = new KInetSocketAddress(*i.netmask); + else + netmask = 0; + if (i.broadcast) + broadcast = new KInetSocketAddress(*i.broadcast); + else + broadcast = 0; + if (i.destination) + destination = new KInetSocketAddress(*i.destination); + else + destination = 0; + return *this; + } + +}; + + +KInetInterface::KInetInterface() : + d(0) { +} + +KInetInterface::KInetInterface(const QString &_name, + int _flags, + KInetSocketAddress *_address, + KInetSocketAddress *_netmask, + KInetSocketAddress *_broadcast, + KInetSocketAddress *_destination) { + d = new KInetInterfacePrivate(_name, _flags, + _address, _netmask, + _broadcast, _destination); +} + +KInetInterface::KInetInterface(const KInetInterface &i) : + d(0) { + if (!i.d) + return; + + d = new KInetInterfacePrivate(); + *d = *i.d; +} + +KInetInterface::~KInetInterface() { + if (d) + delete d; +} + +KInetInterface& KInetInterface::operator =(const KInetInterface& i) { + if (this == &i) + return *this; + + if (d) + delete d; + d = 0; + if (!i.d) + return *this; + + d = new KInetInterfacePrivate(); + *d = *i.d; + return *this; +} + +bool KInetInterface::isValid() const { + return d == 0; +} + +QString KInetInterface::displayName() const { + return d->name; +} + +QString KInetInterface::name() const { + return d->name; +} + +int KInetInterface::flags() const { + return d->flags; +} + +KInetSocketAddress *KInetInterface::address() const { + return d->address; +} + +KInetSocketAddress *KInetInterface::netmask() const { + return d->netmask; +} + +KInetSocketAddress *KInetInterface::broadcastAddress() const { + return d->broadcast; +} + +KInetSocketAddress *KInetInterface::destinationAddress() const { + return d->destination; +} + +KInetSocketAddress *KInetInterface::getPublicInetAddress() { + QValueVector v = getAllInterfaces(true); + + // TODO: first step: take the default route interface + + // try to find point-2-point interface, because it may be + // a dial-up connection. Take it. + QValueVector::const_iterator it = v.begin(); + while (it != v.end()) { + if (((*it).flags() & (PointToPoint | Up | Running)) && + (!((*it).flags() & Loopback)) && + (*it).address() && + ((*it).address()->family() == AF_INET)) + return new KInetSocketAddress(*(*it).address()); + it++; + } + + // otherwise, just take the first non-loopback interface + it = v.begin(); + while (it != v.end()) { + if (((*it).flags() & (Up | Running)) && + (!((*it).flags() & Loopback)) && + (*it).address() && + ((*it).address()->family() == AF_INET)) + return new KInetSocketAddress(*(*it).address()); + it++; + } + + // ok, giving up, try to take loopback + it = v.begin(); + while (it != v.end()) { + if (((*it).flags() & (Up | Running)) && + (*it).address()) + return new KInetSocketAddress(*(*it).address()); + it++; + } + + // not even loopback.. + return 0; +} + +namespace { + KInetSocketAddress *createAddress(struct sockaddr *a) { + if (!a) + return 0; + else if (a->sa_family == AF_INET) + return new KInetSocketAddress((struct sockaddr_in*) a, + sizeof(struct sockaddr_in)); +#ifdef AF_INET6 + else if (a->sa_family == AF_INET6) + return new KInetSocketAddress((struct sockaddr_in6*) a, + sizeof(struct sockaddr_in6)); +#endif + else + return 0; + } + + int convertFlags(int flags) { + int r = 0; + if (flags & IFF_UP) + r |= KInetInterface::Up; + if (flags & IFF_BROADCAST) + r |= KInetInterface::Broadcast; + if (flags & IFF_LOOPBACK) + r |= KInetInterface::Loopback; + if (flags & IFF_POINTOPOINT) + r |= KInetInterface::PointToPoint; + if (flags & IFF_RUNNING) + r |= KInetInterface::Running; + if (flags & IFF_MULTICAST) + r |= KInetInterface::Multicast; + + return r; + } +} + +QValueVector KInetInterface::getAllInterfaces(bool includeLoopback) { + struct kde_ifaddrs *ads; + struct kde_ifaddrs *a; + QValueVector r; + if (kde_getifaddrs(&ads)) + return r; + + a = ads; + while (a) { + if ((a->ifa_flags & IFF_LOOPBACK) && !includeLoopback) { + a = a->ifa_next; + continue; + } + r.push_back(KInetInterface(QString::fromUtf8(a->ifa_name), + convertFlags(a->ifa_flags), + createAddress(a->ifa_addr), + createAddress(a->ifa_netmask), + (a->ifa_flags & IFF_BROADCAST) ? + createAddress(a->ifa_broadaddr) : 0, + (a->ifa_flags & IFF_POINTOPOINT) ? + createAddress(a->ifa_dstaddr) : 0)); + a = a->ifa_next; + } + + kde_freeifaddrs(ads); + return r; +} + -- cgit v1.2.1