File indexing completed on 2023-09-24 04:04:39
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 }