File indexing completed on 2024-03-24 15:27:09

0001 /*  -*- C++ -*-
0002  *  Copyright (C) 2003 Thiago Macieira <thiago@kde.org>
0003  *
0004  *
0005  *  Permission is hereby granted, free of charge, to any person obtaining
0006  *  a copy of this software and associated documentation files (the
0007  *  "Software"), to deal in the Software without restriction, including
0008  *  without limitation the rights to use, copy, modify, merge, publish,
0009  *  distribute, sublicense, and/or sell copies of the Software, and to
0010  *  permit persons to whom the Software is furnished to do so, subject to
0011  *  the following conditions:
0012  *
0013  *  The above copyright notice and this permission notice shall be included
0014  *  in all copies or substantial portions of the Software.
0015  *
0016  *  THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
0017  *  EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
0018  *  MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
0019  *  NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
0020  *  LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
0021  *  OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
0022  *  WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
0023  */
0024 
0025 #include "k3socketaddress.h"
0026 
0027 #include <config-network.h>
0028 #include <config-kdelibs4support.h>
0029 
0030 #include <sys/types.h>
0031 #include <sys/socket.h>
0032 #include <sys/un.h>
0033 #include <arpa/inet.h>
0034 #include <netinet/in.h>
0035 #include <string.h>
0036 #include <stdlib.h>
0037 #include <unistd.h>
0038 
0039 #include <QFile>
0040 #include <QObject>
0041 
0042 #include "klocalizedstring.h"
0043 
0044 #ifndef Q_CC_MSVC
0045 #include "netsupp.h"
0046 #endif
0047 
0048 using namespace KNetwork;
0049 
0050 #if 0
0051 class KIpAddress_localhostV4 : public KIpAddress
0052 {
0053 public:
0054     KIpAddress_localhostV4()
0055     {
0056         *m_data = htonl(0x7f000001);
0057         m_version = 4;
0058     }
0059 };
0060 
0061 class KIpAddress_localhostV6 : public KIpAddress
0062 {
0063 public:
0064     KIpAddress_localhostV6()
0065         : KIpAddress(0L, 6)
0066     {
0067         m_data[3] = htonl(1);
0068     }
0069 };
0070 #endif
0071 
0072 static const char localhostV4_data[] = { 127, 0, 0, 1 };
0073 static const char localhostV6_data[] = { 0, 0, 0, 0,  0, 0, 0, 0,  0, 0, 0, 0,  0, 0, 0, 1 };
0074 
0075 const KIpAddress KIpAddress::localhostV4(&localhostV4_data, 4);
0076 const KIpAddress KIpAddress::localhostV6(&localhostV6_data, 6);
0077 const KIpAddress KIpAddress::anyhostV4(nullptr, 4);
0078 const KIpAddress KIpAddress::anyhostV6(nullptr, 6);
0079 
0080 // helper function to test if an IPv6 v4-mapped address is equal to its IPv4 counterpart
0081 static bool check_v4mapped(const quint32 *v6addr, quint32 v4addr)
0082 {
0083     // check that the v6 is a v4-mapped address
0084     if (!(v6addr[0] == 0 && v6addr[1] == 0 && v6addr[2] == htonl(0x0000ffff))) {
0085         return false;    // not a v4-mapped address
0086     }
0087 
0088     return v6addr[3] == v4addr;
0089 }
0090 
0091 // copy operator
0092 KIpAddress &KIpAddress::operator =(const KIpAddress &other)
0093 {
0094     m_version = other.m_version;
0095     if (m_version == 4 || m_version == 6) {
0096         memcpy(m_data, other.m_data, sizeof(m_data));
0097     }
0098     return *this;
0099 }
0100 
0101 // comparison
0102 bool KIpAddress::compare(const KIpAddress &other, bool checkMapped) const
0103 {
0104     if (m_version == other.m_version)
0105         switch (m_version) {
0106         case 0:
0107             // both objects are empty
0108             return true;
0109 
0110         case 4:
0111             // IPv4 address
0112             return *m_data == *other.m_data;
0113 
0114         case 6:
0115             // IPv6 address
0116             // they are 128-bit long, that is, 16 bytes
0117             return memcmp(m_data, other.m_data, 16) == 0;
0118         }
0119 
0120     if (checkMapped) {
0121         // check the possibility of a v4-mapped address being compared to an IPv4 one
0122         if (m_version == 6 && other.m_version == 4 && check_v4mapped(m_data, *other.m_data)) {
0123             return true;
0124         }
0125 
0126         if (other.m_version == 6 && m_version == 4 && check_v4mapped(other.m_data, *m_data)) {
0127             return true;
0128         }
0129     }
0130 
0131     return false;
0132 }
0133 
0134 // sets the address to the given address
0135 bool KIpAddress::setAddress(const QString &address)
0136 {
0137     m_version = 0;
0138 
0139     // try to guess the address version
0140     if (address.indexOf(QLatin1Char(':')) != -1) {
0141 #ifdef AF_INET6
0142         // guessing IPv6
0143 
0144         quint32 buf[4];
0145         if (inet_pton(AF_INET6, address.toLatin1(), buf)) {
0146             memcpy(m_data, buf, sizeof(m_data));
0147             m_version = 6;
0148             return true;
0149         }
0150 #endif
0151 
0152         return false;
0153     } else {
0154         quint32 buf;
0155         if (inet_pton(AF_INET, address.toLatin1(), &buf)) {
0156             *m_data = buf;
0157             m_version = 4;
0158             return true;
0159         }
0160 
0161         return false;
0162     }
0163 
0164     return false;         // can never happen!
0165 }
0166 
0167 bool KIpAddress::setAddress(const char *address)
0168 {
0169     return setAddress(QLatin1String(address));
0170 }
0171 
0172 // set from binary data
0173 bool KIpAddress::setAddress(const void *raw, int version)
0174 {
0175     // this always succeeds
0176     // except if version is invalid
0177     if (version != 4 && version != 6) {
0178         return false;
0179     }
0180 
0181     m_version = version;
0182     if (raw != nullptr) {
0183         memcpy(m_data, raw, version == 4 ? 4 : 16);
0184     } else {
0185         memset(m_data, 0, 16);
0186     }
0187 
0188     return true;
0189 }
0190 
0191 // presentation form
0192 QString KIpAddress::toString() const
0193 {
0194     char buf[sizeof "1111:2222:3333:4444:5555:6666:255.255.255.255" + 2];
0195     buf[0] = '\0';
0196     switch (m_version) {
0197     case 4:
0198         inet_ntop(AF_INET, (void *)m_data, buf, sizeof(buf) - 1);
0199         return QLatin1String(buf);
0200 
0201     case 6:
0202 #ifdef AF_INET6
0203         inet_ntop(AF_INET6, (void *)m_data, buf, sizeof(buf) - 1);
0204 #endif
0205         return QLatin1String(buf);
0206     }
0207 
0208     return QString();
0209 }
0210 
0211 /*
0212  * An IPv6 socket address
0213  * This is taken from RFC 2553.
0214  */
0215 struct our_sockaddr_in6 {
0216 # if HAVE_STRUCT_SOCKADDR_SA_LEN
0217     quint8        sin6_len;
0218     quint8        sin6_family;
0219 # else  //!HAVE_STRUCT_SOCKADDR_SA_LEN
0220     quint16       sin6_family;
0221 # endif
0222     quint16           sin6_port;  /* RFC says in_port_t */
0223     quint32       sin6_flowinfo;
0224     quint8        sin6_addr[16]; // 24 bytes up to here
0225     quint32       sin6_scope_id; // 28 bytes total
0226 };
0227 
0228 // useful definitions
0229 #define MIN_SOCKADDR_LEN    sizeof(quint16)
0230 #define SOCKADDR_IN_LEN     sizeof(sockaddr_in)
0231 #define MIN_SOCKADDR_IN6_LEN    ((quintptr) &(((our_sockaddr_in6*)0)->sin6_scope_id))
0232 #define SOCKADDR_IN6_LEN    sizeof(our_sockaddr_in6)
0233 #define MIN_SOCKADDR_UN_LEN (sizeof(quint16) + sizeof(char))
0234 
0235 class KNetwork::KSocketAddressData
0236 {
0237 public:
0238     /*
0239      * Note: maybe this should be virtual
0240      * But since the data is shared via the d pointer, it doesn't really matter
0241      * what one class sees, so will the other
0242      */
0243     class QMixSocketAddressRef : public KInetSocketAddress, public KUnixSocketAddress
0244     {
0245     public:
0246         QMixSocketAddressRef(KSocketAddressData *d)
0247             : KInetSocketAddress(d), KUnixSocketAddress(d)
0248         {
0249         }
0250     };
0251     QMixSocketAddressRef ref;
0252 
0253     union {
0254         struct sockaddr         *generic;
0255         struct sockaddr_in      *in;
0256         struct our_sockaddr_in6 *in6;
0257         struct sockaddr_un      *un;
0258     } addr;
0259     quint16 curlen, reallen;
0260 
0261     KSocketAddressData()
0262         : ref(this)
0263     {
0264         addr.generic = nullptr;
0265         curlen = 0;
0266         invalidate();
0267     }
0268 
0269     ~KSocketAddressData()
0270     {
0271         if (addr.generic != nullptr) {
0272             free(addr.generic);
0273         }
0274     }
0275 
0276     inline bool invalid() const
0277     {
0278         return reallen == 0;
0279     }
0280 
0281     inline void invalidate()
0282     {
0283         reallen = 0;
0284     }
0285 
0286     void dup(const sockaddr *sa, quint16 len, bool clear = true);
0287 
0288     void makeipv4()
0289     {
0290         short oldport = 0;
0291         if (!invalid())
0292             switch (addr.generic->sa_family) {
0293             case AF_INET:
0294                 return;       // nothing to do here
0295 #ifdef AF_INET6
0296             case AF_INET6:
0297                 oldport = addr.in6->sin6_port;
0298                 break;
0299 #endif
0300             }
0301 
0302         // create new space
0303         dup(nullptr, SOCKADDR_IN_LEN);
0304 
0305         addr.in->sin_family = AF_INET;
0306 #if HAVE_STRUCT_SOCKADDR_SA_LEN
0307         addr.in->sin_len = SOCKADDR_IN_LEN;
0308 #endif
0309         addr.in->sin_port = oldport;
0310     }
0311 
0312     void makeipv6()
0313     {
0314         short oldport = 0;
0315         if (!invalid())
0316             switch (addr.generic->sa_family) {
0317             case AF_INET:
0318                 oldport = addr.in->sin_port;
0319                 break;
0320 
0321 #ifdef AF_INET6
0322             case AF_INET6:
0323                 return;       // nothing to do here
0324 #endif
0325             }
0326 
0327         // make room
0328         dup(nullptr, SOCKADDR_IN6_LEN);
0329 #ifdef AF_INET6
0330         addr.in6->sin6_family = AF_INET6;
0331 #endif
0332 #if HAVE_STRUCT_SOCKADDR_SA_LEN
0333         addr.in6->sin6_len = SOCKADDR_IN6_LEN;
0334 #endif
0335         addr.in6->sin6_port = oldport;
0336         // sin6_scope_id and sin6_flowid are zero
0337     }
0338 
0339 };
0340 
0341 // create duplicates of
0342 void KSocketAddressData::dup(const sockaddr *sa, quint16 len, bool clear)
0343 {
0344     if (len < MIN_SOCKADDR_LEN) {
0345         // certainly invalid
0346         invalidate();
0347         return;
0348     }
0349 
0350     if (sa && ((sa->sa_family == AF_INET && len < SOCKADDR_IN_LEN) ||
0351 #ifdef AF_INET6
0352                (sa->sa_family == AF_INET6 && len < MIN_SOCKADDR_IN6_LEN) ||
0353 #endif
0354                (sa->sa_family == AF_UNIX && len < MIN_SOCKADDR_UN_LEN))) {
0355         // also invalid
0356         invalidate();
0357         return;
0358     }
0359 
0360     // good
0361     reallen = len;
0362     if (len > curlen) {
0363         if (len < 32) {
0364             curlen = 32;    // big enough for sockaddr_in and sockaddr_in6
0365         } else {
0366             curlen = len;
0367         }
0368         addr.generic = (sockaddr *)realloc(addr.generic, curlen);
0369     }
0370 
0371     if (sa != nullptr) {
0372         memcpy(addr.generic, sa, len); // copy
0373 
0374         // now, normalise the data
0375         if (addr.generic->sa_family == AF_INET) {
0376             reallen = SOCKADDR_IN_LEN;    // no need to be larger
0377         }
0378 #ifdef AF_INET6
0379         else if (addr.generic->sa_family == AF_INET6) {
0380             // set the extra field (sin6_scope_id)
0381 
0382             // the buffer is never smaller than 32 bytes, so this is always
0383             // allowed
0384             if (reallen < SOCKADDR_IN6_LEN) {
0385                 addr.in6->sin6_scope_id = 0;
0386             }
0387 
0388             reallen = SOCKADDR_IN6_LEN;
0389         }
0390 #endif
0391         else if (addr.generic->sa_family == AF_UNIX) {
0392             reallen = MIN_SOCKADDR_UN_LEN + strlen(addr.un->sun_path);
0393         }
0394     } else if (clear) {
0395         memset(addr.generic, 0, len);
0396         addr.generic->sa_family = AF_UNSPEC;
0397     }
0398 }
0399 
0400 // default constructor
0401 KSocketAddress::KSocketAddress()
0402     : d(new KSocketAddressData)
0403 {
0404 }
0405 
0406 // constructor from binary data
0407 KSocketAddress::KSocketAddress(const sockaddr *sa, quint16 len)
0408     : d(new KSocketAddressData)
0409 {
0410     setAddress(sa, len);
0411 }
0412 
0413 KSocketAddress::KSocketAddress(const KSocketAddress &other)
0414     : d(new(KSocketAddressData))
0415 {
0416     *this = other;
0417 }
0418 
0419 KSocketAddress::KSocketAddress(KSocketAddressData *d2)
0420     : d(d2)
0421 {
0422 }
0423 
0424 KSocketAddress::~KSocketAddress()
0425 {
0426     // prevent double-deletion, since we're already being deleted
0427     if (d) {
0428         d->ref.KInetSocketAddress::d = nullptr;
0429         d->ref.KUnixSocketAddress::d = nullptr;
0430         delete d;
0431     }
0432 }
0433 
0434 KSocketAddress &KSocketAddress::operator =(const KSocketAddress &other)
0435 {
0436     if (other.d && !other.d->invalid()) {
0437         d->dup(other.d->addr.generic, other.d->reallen);
0438     } else {
0439         d->invalidate();
0440     }
0441     return *this;
0442 }
0443 
0444 const sockaddr *KSocketAddress::address() const
0445 {
0446     if (d->invalid()) {
0447         return nullptr;
0448     }
0449     return d->addr.generic;
0450 }
0451 
0452 sockaddr *KSocketAddress::address()
0453 {
0454     if (d->invalid()) {
0455         return nullptr;
0456     }
0457     return d->addr.generic;
0458 }
0459 
0460 KSocketAddress &KSocketAddress::setAddress(const sockaddr *sa, quint16 len)
0461 {
0462     if (sa != nullptr && len >= MIN_SOCKADDR_LEN) {
0463         d->dup(sa, len);
0464     } else {
0465         d->invalidate();
0466     }
0467 
0468     return *this;
0469 }
0470 
0471 quint16 KSocketAddress::length() const
0472 {
0473     if (d->invalid()) {
0474         return 0;
0475     }
0476     return d->reallen;
0477 }
0478 
0479 KSocketAddress &KSocketAddress::setLength(quint16 len)
0480 {
0481     d->dup((sockaddr *)nullptr, len, false);
0482 
0483     return *this;
0484 }
0485 
0486 int KSocketAddress::family() const
0487 {
0488     if (d->invalid()) {
0489         return AF_UNSPEC;
0490     }
0491     return d->addr.generic->sa_family;
0492 }
0493 
0494 KSocketAddress &KSocketAddress::setFamily(int family)
0495 {
0496     if (d->invalid()) {
0497         d->dup((sockaddr *)nullptr, MIN_SOCKADDR_LEN);
0498     }
0499     d->addr.generic->sa_family = family;
0500 
0501     return *this;
0502 }
0503 
0504 bool KSocketAddress::operator ==(const KSocketAddress &other) const
0505 {
0506     // if this is invalid, it's only equal if the other one is invalid as well
0507     if (d->invalid()) {
0508         return other.d->invalid();
0509     }
0510 
0511     // check the family to make sure we don't do unnecessary comparison
0512     if (d->addr.generic->sa_family != other.d->addr.generic->sa_family) {
0513         return false;    // not the same family, not equal
0514     }
0515 
0516     // same family then
0517     // check the ones we know already
0518     switch (d->addr.generic->sa_family) {
0519     case AF_INET:
0520         Q_ASSERT(d->reallen == SOCKADDR_IN_LEN);
0521         Q_ASSERT(other.d->reallen == SOCKADDR_IN_LEN);
0522         return memcmp(d->addr.in, other.d->addr.in, SOCKADDR_IN_LEN) == 0;
0523 
0524 #ifdef AF_INET6
0525     case AF_INET6:
0526         Q_ASSERT(d->reallen >= MIN_SOCKADDR_IN6_LEN);
0527         Q_ASSERT(other.d->reallen >= MIN_SOCKADDR_IN6_LEN);
0528 
0529 # if !HAVE_STRUCT_SOCKADDR_IN6 || defined(HAVE_STRUCT_SOCKADDR_IN6_SIN6_SCOPE_ID)
0530         // check for the case where sin6_scope_id isn't present
0531         if (d->reallen != other.d->reallen) {
0532             if (memcmp(d->addr.in6, other.d->addr.in6, MIN_SOCKADDR_IN6_LEN) != 0) {
0533                 return false;    // not equal
0534             }
0535             if (d->reallen > other.d->reallen) {
0536                 return d->addr.in6->sin6_scope_id == 0;
0537             } else {
0538                 return other.d->addr.in6->sin6_scope_id == 0;
0539             }
0540         }
0541 # endif
0542 
0543         return memcmp(d->addr.in6, other.d->addr.in6, d->reallen) == 0;
0544 #endif
0545 
0546     case AF_UNIX:
0547         Q_ASSERT(d->reallen >= MIN_SOCKADDR_UN_LEN);
0548         Q_ASSERT(other.d->reallen >= MIN_SOCKADDR_UN_LEN);
0549 
0550         // do a string comparison here
0551         return strcmp(d->addr.un->sun_path, other.d->addr.un->sun_path) == 0;
0552 
0553     default:
0554         // something else we don't know about
0555         // they are equal if and only if they are exactly equal
0556         if (d->reallen == other.d->reallen) {
0557             return memcmp(d->addr.generic, other.d->addr.generic, d->reallen) == 0;
0558         }
0559     }
0560 
0561     return false;     // not equal in any other case
0562 }
0563 
0564 QString KSocketAddress::nodeName() const
0565 {
0566     if (d->invalid()) {
0567         return QString();
0568     }
0569 
0570     switch (d->addr.generic->sa_family) {
0571     case AF_INET:
0572 #ifdef AF_INET6
0573     case AF_INET6:
0574 
0575         QString scopeid(QLatin1Char('%'));
0576         if (d->addr.generic->sa_family == AF_INET6 && d->addr.in6->sin6_scope_id) {
0577             scopeid += QString::number(d->addr.in6->sin6_scope_id);
0578         } else {
0579             scopeid.truncate(0);
0580         }
0581         return d->ref.ipAddress().toString() + scopeid;
0582 #else
0583         return d->ref.ipAddress().toString();
0584 #endif
0585     }
0586 
0587     // any other case, including AF_UNIX
0588     return QString();
0589 }
0590 
0591 QString KSocketAddress::serviceName() const
0592 {
0593     if (d->invalid()) {
0594         return QString();
0595     }
0596 
0597     switch (d->addr.generic->sa_family) {
0598     case AF_INET:
0599 #ifdef AF_INET6
0600     case AF_INET6:
0601 #endif
0602         return QString::number(d->ref.port());
0603 
0604     case AF_UNIX:
0605         return d->ref.pathname();
0606     }
0607 
0608     return QString();
0609 }
0610 
0611 QString KSocketAddress::toString() const
0612 {
0613     if (d->invalid()) {
0614         return QString();
0615     }
0616 
0617     QString fmt;
0618 
0619     if (d->addr.generic->sa_family == AF_INET) {
0620         fmt = QLatin1String("%1:%2");
0621     }
0622 #ifdef AF_INET6
0623     else if (d->addr.generic->sa_family == AF_INET6) {
0624         fmt = QLatin1String("[%1]:%2");
0625     }
0626 #endif
0627     else if (d->addr.generic->sa_family == AF_UNIX) {
0628         return QString(QLatin1String("unix:%1")).arg(serviceName());
0629     } else
0630         return i18nc("1: the unknown socket address family number",
0631                      "Unknown family %1", d->addr.generic->sa_family);
0632 
0633     return fmt.arg(nodeName()).arg(serviceName());
0634 }
0635 
0636 KInetSocketAddress &KSocketAddress::asInet()
0637 {
0638     return d->ref;
0639 }
0640 
0641 KInetSocketAddress KSocketAddress::asInet() const
0642 {
0643     return d->ref;
0644 }
0645 
0646 KUnixSocketAddress &KSocketAddress::asUnix()
0647 {
0648     return d->ref;
0649 }
0650 
0651 KUnixSocketAddress KSocketAddress::asUnix() const
0652 {
0653     return d->ref;
0654 }
0655 
0656 int KSocketAddress::ianaFamily(int af)
0657 {
0658     switch (af) {
0659     case AF_INET:
0660         return 1;
0661 
0662 #ifdef AF_INET6
0663     case AF_INET6:
0664         return 2;
0665 #endif
0666 
0667     default:
0668         return 0;
0669     }
0670 }
0671 
0672 int KSocketAddress::fromIanaFamily(int iana)
0673 {
0674     switch (iana) {
0675     case 1:
0676         return AF_INET;
0677 
0678 #ifdef AF_INET6
0679     case 2:
0680         return AF_INET6;
0681 #endif
0682 
0683     default:
0684         return AF_UNSPEC;
0685     }
0686 }
0687 
0688 // default constructor
0689 KInetSocketAddress::KInetSocketAddress()
0690 {
0691 }
0692 
0693 // binary data constructor
0694 KInetSocketAddress::KInetSocketAddress(const sockaddr *sa, quint16 len)
0695     : KSocketAddress(sa, len)
0696 {
0697     if (!d->invalid()) {
0698         update();
0699     }
0700 }
0701 
0702 // create from IP and port
0703 KInetSocketAddress::KInetSocketAddress(const KIpAddress &host, quint16 port)
0704 {
0705     setHost(host);
0706     setPort(port);
0707 }
0708 
0709 // copy constructor
0710 KInetSocketAddress::KInetSocketAddress(const KInetSocketAddress &other)
0711     : KSocketAddress(other)
0712 {
0713 }
0714 
0715 // special copy constructor
0716 KInetSocketAddress::KInetSocketAddress(const KSocketAddress &other)
0717     : KSocketAddress(other)
0718 {
0719     if (!d->invalid()) {
0720         update();
0721     }
0722 }
0723 
0724 // special constructor
0725 KInetSocketAddress::KInetSocketAddress(KSocketAddressData *d)
0726     : KSocketAddress(d)
0727 {
0728 }
0729 
0730 // destructor
0731 KInetSocketAddress::~KInetSocketAddress()
0732 {
0733     /* nothing to do */
0734 }
0735 
0736 // copy operator
0737 KInetSocketAddress &KInetSocketAddress::operator =(const KInetSocketAddress &other)
0738 {
0739     KSocketAddress::operator =(other);
0740     return *this;
0741 }
0742 
0743 // IP version
0744 int KInetSocketAddress::ipVersion() const
0745 {
0746     if (d->invalid()) {
0747         return 0;
0748     }
0749 
0750     switch (d->addr.generic->sa_family) {
0751     case AF_INET:
0752         return 4;
0753 
0754 #ifdef AF_INET6
0755     case AF_INET6:
0756         return 6;
0757 #endif
0758     }
0759 
0760     return 0;         // for all other cases
0761 }
0762 
0763 KIpAddress KInetSocketAddress::ipAddress() const
0764 {
0765     if (d->invalid()) {
0766         return KIpAddress();    // return an empty address as well
0767     }
0768 
0769     switch (d->addr.generic->sa_family) {
0770     case AF_INET:
0771         return KIpAddress(&d->addr.in->sin_addr, 4);
0772 #ifdef AF_INET6
0773     case AF_INET6:
0774         return KIpAddress(&d->addr.in6->sin6_addr, 6);
0775 #endif
0776     }
0777 
0778     return KIpAddress();      // empty in all other cases
0779 }
0780 
0781 KInetSocketAddress &KInetSocketAddress::setHost(const KIpAddress &ip)
0782 {
0783     switch (ip.version()) {
0784     case 4:
0785         makeIPv4();
0786         memcpy(&d->addr.in->sin_addr, ip.addr(), sizeof(d->addr.in->sin_addr));
0787         break;
0788 
0789     case 6:
0790         makeIPv6();
0791         memcpy(&d->addr.in6->sin6_addr, ip.addr(), sizeof(d->addr.in6->sin6_addr));
0792         break;
0793 
0794     default:
0795         // empty
0796         d->invalidate();
0797     }
0798 
0799     return *this;
0800 }
0801 
0802 // returns the port
0803 quint16 KInetSocketAddress::port() const
0804 {
0805     if (d->invalid()) {
0806         return 0;
0807     }
0808 
0809     switch (d->addr.generic->sa_family) {
0810     case AF_INET:
0811         return ntohs(d->addr.in->sin_port);
0812 
0813 #ifdef AF_INET6
0814     case AF_INET6:
0815         return ntohs(d->addr.in6->sin6_port);
0816 #endif
0817     }
0818 
0819     return 0;
0820 }
0821 
0822 KInetSocketAddress &KInetSocketAddress::setPort(quint16 port)
0823 {
0824     if (d->invalid()) {
0825         makeIPv4();
0826     }
0827 
0828     switch (d->addr.generic->sa_family) {
0829     case AF_INET:
0830         d->addr.in->sin_port = htons(port);
0831         break;
0832 
0833 #ifdef AF_INET6
0834     case AF_INET6:
0835         d->addr.in6->sin6_port = htons(port);
0836         break;
0837 #endif
0838 
0839     default:
0840         d->invalidate();      // setting the port on something else
0841     }
0842 
0843     return *this;
0844 }
0845 
0846 KInetSocketAddress &KInetSocketAddress::makeIPv4()
0847 {
0848     d->makeipv4();
0849     return *this;
0850 }
0851 
0852 KInetSocketAddress &KInetSocketAddress::makeIPv6()
0853 {
0854     d->makeipv6();
0855     return *this;
0856 }
0857 
0858 quint32 KInetSocketAddress::flowinfo() const
0859 {
0860 #ifndef AF_INET6
0861     return 0;
0862 #else
0863 
0864     if (!d->invalid() && d->addr.in6->sin6_family == AF_INET6) {
0865         return d->addr.in6->sin6_flowinfo;
0866     }
0867     return 0;
0868 #endif
0869 }
0870 
0871 KInetSocketAddress &KInetSocketAddress::setFlowinfo(quint32 flowinfo)
0872 {
0873     makeIPv6();           // must set here
0874     d->addr.in6->sin6_flowinfo = flowinfo;
0875     return *this;
0876 }
0877 
0878 int KInetSocketAddress::scopeId() const
0879 {
0880 #ifndef AF_INET6
0881     return 0;
0882 #else
0883 
0884     if (!d->invalid() && d->addr.in6->sin6_family == AF_INET6) {
0885         return d->addr.in6->sin6_scope_id;
0886     }
0887     return 0;
0888 #endif
0889 }
0890 
0891 KInetSocketAddress &KInetSocketAddress::setScopeId(int scopeid)
0892 {
0893     makeIPv6();           // must set here
0894     d->addr.in6->sin6_scope_id = scopeid;
0895     return *this;
0896 }
0897 
0898 void KInetSocketAddress::update()
0899 {
0900     if (d->addr.generic->sa_family == AF_INET) {
0901         return;
0902     }
0903 #ifdef AF_INET6
0904     else if (d->addr.generic->sa_family == AF_INET6) {
0905         return;
0906     }
0907 #endif
0908     else {
0909         d->invalidate();
0910     }
0911 }
0912 
0913 KUnixSocketAddress::KUnixSocketAddress()
0914 {
0915 }
0916 
0917 KUnixSocketAddress::KUnixSocketAddress(const sockaddr *sa, quint16 len)
0918     : KSocketAddress(sa, len)
0919 {
0920     if (!d->invalid() && d->addr.un->sun_family != AF_UNIX) {
0921         d->invalidate();
0922     }
0923 }
0924 
0925 KUnixSocketAddress::KUnixSocketAddress(const KUnixSocketAddress &other)
0926     : KSocketAddress(other)
0927 {
0928 }
0929 
0930 KUnixSocketAddress::KUnixSocketAddress(const QString &pathname)
0931 {
0932     setPathname(pathname);
0933 }
0934 
0935 KUnixSocketAddress::KUnixSocketAddress(KSocketAddressData *d)
0936     : KSocketAddress(d)
0937 {
0938 }
0939 
0940 KUnixSocketAddress::~KUnixSocketAddress()
0941 {
0942 }
0943 
0944 KUnixSocketAddress &KUnixSocketAddress::operator =(const KUnixSocketAddress &other)
0945 {
0946     KSocketAddress::operator =(other);
0947     return *this;
0948 }
0949 
0950 QString KUnixSocketAddress::pathname() const
0951 {
0952     if (!d->invalid() && d->addr.un->sun_family == AF_UNIX) {
0953         return QFile::decodeName(d->addr.un->sun_path);
0954     }
0955     return QString();
0956 }
0957 
0958 KUnixSocketAddress &KUnixSocketAddress::setPathname(const QString &path)
0959 {
0960     d->dup(nullptr, MIN_SOCKADDR_UN_LEN + path.length());
0961     d->addr.un->sun_family = AF_UNIX;
0962     strcpy(d->addr.un->sun_path, QFile::encodeName(path));
0963 
0964 #if HAVE_STRUCT_SOCKADDR_SA_LEN
0965     d->addr.un->sun_len = d->reallen;
0966 #endif
0967 
0968     return *this;
0969 }