KDECore
k3socketaddress.cpp
Go to the documentation of this file.
00001 /* -*- C++ -*- 00002 * Copyright (C) 2003 Thiago Macieira <thiago@kde.org> 00003 * 00004 * 00005 * Permission is hereby granted, free of charge, to any person obtaining 00006 * a copy of this software and associated documentation files (the 00007 * "Software"), to deal in the Software without restriction, including 00008 * without limitation the rights to use, copy, modify, merge, publish, 00009 * distribute, sublicense, and/or sell copies of the Software, and to 00010 * permit persons to whom the Software is furnished to do so, subject to 00011 * the following conditions: 00012 * 00013 * The above copyright notice and this permission notice shall be included 00014 * in all copies or substantial portions of the Software. 00015 * 00016 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, 00017 * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 00018 * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND 00019 * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE 00020 * LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION 00021 * OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION 00022 * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 00023 */ 00024 00025 #include "k3socketaddress.h" 00026 00027 #include <config.h> 00028 #include <config-network.h> 00029 00030 #include <sys/types.h> 00031 #include <sys/socket.h> 00032 #include <sys/un.h> 00033 #include <arpa/inet.h> 00034 #include <netinet/in.h> 00035 #include <string.h> 00036 #include <stdlib.h> 00037 #include <unistd.h> 00038 00039 #include <QFile> 00040 #include <QObject> 00041 00042 #include "klocale.h" 00043 00044 #ifndef Q_CC_MSVC 00045 #include "netsupp.h" 00046 #endif 00047 00048 using namespace KNetwork; 00049 00050 #if 0 00051 class KIpAddress_localhostV4 : public KIpAddress 00052 { 00053 public: 00054 KIpAddress_localhostV4() 00055 { 00056 *m_data = htonl(0x7f000001); 00057 m_version = 4; 00058 } 00059 }; 00060 00061 class KIpAddress_localhostV6 : public KIpAddress 00062 { 00063 public: 00064 KIpAddress_localhostV6() 00065 : KIpAddress(0L, 6) 00066 { 00067 m_data[3] = htonl(1); 00068 } 00069 }; 00070 #endif 00071 00072 static const char localhostV4_data[] = { 127, 0, 0, 1 }; 00073 static const char localhostV6_data[] = { 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,1 }; 00074 00075 const KIpAddress KIpAddress::localhostV4(&localhostV4_data, 4); 00076 const KIpAddress KIpAddress::localhostV6(&localhostV6_data, 6); 00077 const KIpAddress KIpAddress::anyhostV4(0L, 4); 00078 const KIpAddress KIpAddress::anyhostV6(0L, 6); 00079 00080 // helper function to test if an IPv6 v4-mapped address is equal to its IPv4 counterpart 00081 static bool check_v4mapped(const quint32* v6addr, quint32 v4addr) 00082 { 00083 // check that the v6 is a v4-mapped address 00084 if (!(v6addr[0] == 0 && v6addr[1] == 0 && v6addr[2] == htonl(0x0000ffff))) 00085 return false; // not a v4-mapped address 00086 00087 return v6addr[3] == v4addr; 00088 } 00089 00090 // copy operator 00091 KIpAddress& KIpAddress::operator =(const KIpAddress& other) 00092 { 00093 m_version = other.m_version; 00094 if (m_version == 4 || m_version == 6) 00095 memcpy(m_data, other.m_data, sizeof(m_data)); 00096 return *this; 00097 } 00098 00099 // comparison 00100 bool KIpAddress::compare(const KIpAddress& other, bool checkMapped) const 00101 { 00102 if (m_version == other.m_version) 00103 switch (m_version) 00104 { 00105 case 0: 00106 // both objects are empty 00107 return true; 00108 00109 case 4: 00110 // IPv4 address 00111 return *m_data == *other.m_data; 00112 00113 case 6: 00114 // IPv6 address 00115 // they are 128-bit long, that is, 16 bytes 00116 return memcmp(m_data, other.m_data, 16) == 0; 00117 } 00118 00119 if (checkMapped) 00120 { 00121 // check the possibility of a v4-mapped address being compared to an IPv4 one 00122 if (m_version == 6 && other.m_version == 4 && check_v4mapped(m_data, *other.m_data)) 00123 return true; 00124 00125 if (other.m_version == 6 && m_version == 4 && check_v4mapped(other.m_data, *m_data)) 00126 return true; 00127 } 00128 00129 return false; 00130 } 00131 00132 // sets the address to the given address 00133 bool KIpAddress::setAddress(const QString& address) 00134 { 00135 m_version = 0; 00136 00137 // try to guess the address version 00138 if (address.indexOf(QLatin1Char(':')) != -1) 00139 { 00140 #ifdef AF_INET6 00141 // guessing IPv6 00142 00143 quint32 buf[4]; 00144 if (inet_pton(AF_INET6, address.toLatin1(), buf)) 00145 { 00146 memcpy(m_data, buf, sizeof(m_data)); 00147 m_version = 6; 00148 return true; 00149 } 00150 #endif 00151 00152 return false; 00153 } 00154 else 00155 { 00156 quint32 buf; 00157 if (inet_pton(AF_INET, address.toLatin1(), &buf)) 00158 { 00159 *m_data = buf; 00160 m_version = 4; 00161 return true; 00162 } 00163 00164 return false; 00165 } 00166 00167 return false; // can never happen! 00168 } 00169 00170 bool KIpAddress::setAddress(const char* address) 00171 { 00172 return setAddress(QLatin1String(address)); 00173 } 00174 00175 // set from binary data 00176 bool KIpAddress::setAddress(const void* raw, int version) 00177 { 00178 // this always succeeds 00179 // except if version is invalid 00180 if (version != 4 && version != 6) 00181 return false; 00182 00183 m_version = version; 00184 if (raw != 0L) 00185 memcpy(m_data, raw, version == 4 ? 4 : 16); 00186 else 00187 memset(m_data, 0, 16); 00188 00189 return true; 00190 } 00191 00192 // presentation form 00193 QString KIpAddress::toString() const 00194 { 00195 char buf[sizeof "1111:2222:3333:4444:5555:6666:255.255.255.255" + 2]; 00196 buf[0] = '\0'; 00197 switch (m_version) 00198 { 00199 case 4: 00200 inet_ntop(AF_INET, (void*)m_data, buf, sizeof(buf) - 1); 00201 return QLatin1String(buf); 00202 00203 case 6: 00204 #ifdef AF_INET6 00205 inet_ntop(AF_INET6, (void*)m_data, buf, sizeof(buf) - 1); 00206 #endif 00207 return QLatin1String(buf); 00208 } 00209 00210 return QString(); 00211 } 00212 00213 /* 00214 * An IPv6 socket address 00215 * This is taken from RFC 2553. 00216 */ 00217 struct our_sockaddr_in6 00218 { 00219 # ifdef HAVE_STRUCT_SOCKADDR_SA_LEN 00220 quint8 sin6_len; 00221 quint8 sin6_family; 00222 # else //!HAVE_STRUCT_SOCKADDR_SA_LEN 00223 quint16 sin6_family; 00224 # endif 00225 quint16 sin6_port; /* RFC says in_port_t */ 00226 quint32 sin6_flowinfo; 00227 quint8 sin6_addr[16]; // 24 bytes up to here 00228 quint32 sin6_scope_id; // 28 bytes total 00229 }; 00230 00231 // useful definitions 00232 #define MIN_SOCKADDR_LEN sizeof(quint16) 00233 #define SOCKADDR_IN_LEN sizeof(sockaddr_in) 00234 #define MIN_SOCKADDR_IN6_LEN ((quintptr) &(((our_sockaddr_in6*)0)->sin6_scope_id)) 00235 #define SOCKADDR_IN6_LEN sizeof(our_sockaddr_in6) 00236 #define MIN_SOCKADDR_UN_LEN (sizeof(quint16) + sizeof(char)) 00237 00238 00239 class KNetwork::KSocketAddressData 00240 { 00241 public: 00242 /* 00243 * Note: maybe this should be virtual 00244 * But since the data is shared via the d pointer, it doesn't really matter 00245 * what one class sees, so will the other 00246 */ 00247 class QMixSocketAddressRef : public KInetSocketAddress, public KUnixSocketAddress 00248 { 00249 public: 00250 QMixSocketAddressRef(KSocketAddressData* d) 00251 : KInetSocketAddress(d), KUnixSocketAddress(d) 00252 { 00253 } 00254 }; 00255 QMixSocketAddressRef ref; 00256 00257 union 00258 { 00259 struct sockaddr *generic; 00260 struct sockaddr_in *in; 00261 struct our_sockaddr_in6 *in6; 00262 struct sockaddr_un *un; 00263 } addr; 00264 quint16 curlen, reallen; 00265 00266 KSocketAddressData() 00267 : ref(this) 00268 { 00269 addr.generic = 0L; 00270 curlen = 0; 00271 invalidate(); 00272 } 00273 00274 ~KSocketAddressData() 00275 { 00276 if (addr.generic != 0L) 00277 free(addr.generic); 00278 } 00279 00280 inline bool invalid() const 00281 { return reallen == 0; } 00282 00283 inline void invalidate() 00284 { reallen = 0; } 00285 00286 void dup(const sockaddr* sa, quint16 len, bool clear = true); 00287 00288 void makeipv4() 00289 { 00290 short oldport = 0; 00291 if (!invalid()) 00292 switch (addr.generic->sa_family) 00293 { 00294 case AF_INET: 00295 return; // nothing to do here 00296 #ifdef AF_INET6 00297 case AF_INET6: 00298 oldport = addr.in6->sin6_port; 00299 break; 00300 #endif 00301 } 00302 00303 // create new space 00304 dup(0L, SOCKADDR_IN_LEN); 00305 00306 addr.in->sin_family = AF_INET; 00307 #ifdef HAVE_STRUCT_SOCKADDR_SA_LEN 00308 addr.in->sin_len = SOCKADDR_IN_LEN; 00309 #endif 00310 addr.in->sin_port = oldport; 00311 } 00312 00313 void makeipv6() 00314 { 00315 short oldport = 0; 00316 if (!invalid()) 00317 switch (addr.generic->sa_family) 00318 { 00319 case AF_INET: 00320 oldport = addr.in->sin_port; 00321 break; 00322 00323 #ifdef AF_INET6 00324 case AF_INET6: 00325 return; // nothing to do here 00326 #endif 00327 } 00328 00329 // make room 00330 dup(0L, SOCKADDR_IN6_LEN); 00331 #ifdef AF_INET6 00332 addr.in6->sin6_family = AF_INET6; 00333 #endif 00334 #ifdef HAVE_STRUCT_SOCKADDR_SA_LEN 00335 addr.in6->sin6_len = SOCKADDR_IN6_LEN; 00336 #endif 00337 addr.in6->sin6_port = oldport; 00338 // sin6_scope_id and sin6_flowid are zero 00339 } 00340 00341 }; 00342 00343 // create duplicates of 00344 void KSocketAddressData::dup(const sockaddr* sa, quint16 len, bool clear) 00345 { 00346 if (len < MIN_SOCKADDR_LEN) 00347 { 00348 // certainly invalid 00349 invalidate(); 00350 return; 00351 } 00352 00353 if (sa && ((sa->sa_family == AF_INET && len < SOCKADDR_IN_LEN) || 00354 #ifdef AF_INET6 00355 (sa->sa_family == AF_INET6 && len < MIN_SOCKADDR_IN6_LEN) || 00356 #endif 00357 (sa->sa_family == AF_UNIX && len < MIN_SOCKADDR_UN_LEN))) 00358 { 00359 // also invalid 00360 invalidate(); 00361 return; 00362 } 00363 00364 // good 00365 reallen = len; 00366 if (len > curlen) 00367 { 00368 if (len < 32) 00369 curlen = 32; // big enough for sockaddr_in and sockaddr_in6 00370 else 00371 curlen = len; 00372 addr.generic = (sockaddr*)realloc(addr.generic, curlen); 00373 } 00374 00375 if (sa != 0L) 00376 { 00377 memcpy(addr.generic, sa, len); // copy 00378 00379 // now, normalise the data 00380 if (addr.generic->sa_family == AF_INET) 00381 reallen = SOCKADDR_IN_LEN; // no need to be larger 00382 #ifdef AF_INET6 00383 else if (addr.generic->sa_family == AF_INET6) 00384 { 00385 // set the extra field (sin6_scope_id) 00386 00387 // the buffer is never smaller than 32 bytes, so this is always 00388 // allowed 00389 if (reallen < SOCKADDR_IN6_LEN) 00390 addr.in6->sin6_scope_id = 0; 00391 00392 reallen = SOCKADDR_IN6_LEN; 00393 } 00394 #endif 00395 else if (addr.generic->sa_family == AF_UNIX) 00396 reallen = MIN_SOCKADDR_UN_LEN + strlen(addr.un->sun_path); 00397 } 00398 else if (clear) 00399 { 00400 memset(addr.generic, 0, len); 00401 addr.generic->sa_family = AF_UNSPEC; 00402 } 00403 } 00404 00405 // default constructor 00406 KSocketAddress::KSocketAddress() 00407 : d(new KSocketAddressData) 00408 { 00409 } 00410 00411 // constructor from binary data 00412 KSocketAddress::KSocketAddress(const sockaddr *sa, quint16 len) 00413 : d(new KSocketAddressData) 00414 { 00415 setAddress(sa, len); 00416 } 00417 00418 KSocketAddress::KSocketAddress(const KSocketAddress& other) 00419 : d(new(KSocketAddressData)) 00420 { 00421 *this = other; 00422 } 00423 00424 KSocketAddress::KSocketAddress(KSocketAddressData *d2) 00425 : d(d2) 00426 { 00427 } 00428 00429 KSocketAddress::~KSocketAddress() 00430 { 00431 // prevent double-deletion, since we're already being deleted 00432 if (d) 00433 { 00434 d->ref.KInetSocketAddress::d = 0L; 00435 d->ref.KUnixSocketAddress::d = 0L; 00436 delete d; 00437 } 00438 } 00439 00440 KSocketAddress& KSocketAddress::operator =(const KSocketAddress& other) 00441 { 00442 if (other.d && !other.d->invalid()) 00443 d->dup(other.d->addr.generic, other.d->reallen); 00444 else 00445 d->invalidate(); 00446 return *this; 00447 } 00448 00449 const sockaddr* KSocketAddress::address() const 00450 { 00451 if (d->invalid()) 00452 return 0L; 00453 return d->addr.generic; 00454 } 00455 00456 sockaddr* KSocketAddress::address() 00457 { 00458 if (d->invalid()) 00459 return 0L; 00460 return d->addr.generic; 00461 } 00462 00463 KSocketAddress& KSocketAddress::setAddress(const sockaddr* sa, quint16 len) 00464 { 00465 if (sa != 0L && len >= MIN_SOCKADDR_LEN) 00466 d->dup(sa, len); 00467 else 00468 d->invalidate(); 00469 00470 return *this; 00471 } 00472 00473 quint16 KSocketAddress::length() const 00474 { 00475 if (d->invalid()) 00476 return 0; 00477 return d->reallen; 00478 } 00479 00480 KSocketAddress& KSocketAddress::setLength(quint16 len) 00481 { 00482 d->dup((sockaddr*)0L, len, false); 00483 00484 return *this; 00485 } 00486 00487 int KSocketAddress::family() const 00488 { 00489 if (d->invalid()) 00490 return AF_UNSPEC; 00491 return d->addr.generic->sa_family; 00492 } 00493 00494 KSocketAddress& KSocketAddress::setFamily(int family) 00495 { 00496 if (d->invalid()) 00497 d->dup((sockaddr*)0L, MIN_SOCKADDR_LEN); 00498 d->addr.generic->sa_family = family; 00499 00500 return *this; 00501 } 00502 00503 bool KSocketAddress::operator ==(const KSocketAddress& other) const 00504 { 00505 // if this is invalid, it's only equal if the other one is invalid as well 00506 if (d->invalid()) 00507 return other.d->invalid(); 00508 00509 // check the family to make sure we don't do unnecessary comparison 00510 if (d->addr.generic->sa_family != other.d->addr.generic->sa_family) 00511 return false; // not the same family, not equal 00512 00513 // same family then 00514 // check the ones we know already 00515 switch (d->addr.generic->sa_family) 00516 { 00517 case AF_INET: 00518 Q_ASSERT(d->reallen == SOCKADDR_IN_LEN); 00519 Q_ASSERT(other.d->reallen == SOCKADDR_IN_LEN); 00520 return memcmp(d->addr.in, other.d->addr.in, SOCKADDR_IN_LEN) == 0; 00521 00522 #ifdef AF_INET6 00523 case AF_INET6: 00524 Q_ASSERT(d->reallen >= MIN_SOCKADDR_IN6_LEN); 00525 Q_ASSERT(other.d->reallen >= MIN_SOCKADDR_IN6_LEN); 00526 00527 # if !defined(HAVE_STRUCT_SOCKADDR_IN6) || defined(HAVE_STRUCT_SOCKADDR_IN6_SIN6_SCOPE_ID) 00528 // check for the case where sin6_scope_id isn't present 00529 if (d->reallen != other.d->reallen) 00530 { 00531 if (memcmp(d->addr.in6, other.d->addr.in6, MIN_SOCKADDR_IN6_LEN) != 0) 00532 return false; // not equal 00533 if (d->reallen > other.d->reallen) 00534 return d->addr.in6->sin6_scope_id == 0; 00535 else 00536 return other.d->addr.in6->sin6_scope_id == 0; 00537 } 00538 # endif 00539 00540 return memcmp(d->addr.in6, other.d->addr.in6, d->reallen) == 0; 00541 #endif 00542 00543 case AF_UNIX: 00544 Q_ASSERT(d->reallen >= MIN_SOCKADDR_UN_LEN); 00545 Q_ASSERT(other.d->reallen >= MIN_SOCKADDR_UN_LEN); 00546 00547 // do a string comparison here 00548 return strcmp(d->addr.un->sun_path, other.d->addr.un->sun_path) == 0; 00549 00550 default: 00551 // something else we don't know about 00552 // they are equal if and only if they are exactly equal 00553 if (d->reallen == other.d->reallen) 00554 return memcmp(d->addr.generic, other.d->addr.generic, d->reallen) == 0; 00555 } 00556 00557 return false; // not equal in any other case 00558 } 00559 00560 QString KSocketAddress::nodeName() const 00561 { 00562 if (d->invalid()) 00563 return QString(); 00564 00565 switch (d->addr.generic->sa_family) 00566 { 00567 case AF_INET: 00568 #ifdef AF_INET6 00569 case AF_INET6: 00570 00571 QString scopeid(QLatin1Char('%')); 00572 if (d->addr.generic->sa_family == AF_INET6 && d->addr.in6->sin6_scope_id) 00573 scopeid += QString::number(d->addr.in6->sin6_scope_id); 00574 else 00575 scopeid.truncate(0); 00576 return d->ref.ipAddress().toString() + scopeid; 00577 #else 00578 return d->ref.ipAddress().toString(); 00579 #endif 00580 } 00581 00582 // any other case, including AF_UNIX 00583 return QString(); 00584 } 00585 00586 QString KSocketAddress::serviceName() const 00587 { 00588 if (d->invalid()) 00589 return QString(); 00590 00591 switch (d->addr.generic->sa_family) 00592 { 00593 case AF_INET: 00594 #ifdef AF_INET6 00595 case AF_INET6: 00596 #endif 00597 return QString::number(d->ref.port()); 00598 00599 case AF_UNIX: 00600 return d->ref.pathname(); 00601 } 00602 00603 return QString(); 00604 } 00605 00606 QString KSocketAddress::toString() const 00607 { 00608 if (d->invalid()) 00609 return QString(); 00610 00611 QString fmt; 00612 00613 if (d->addr.generic->sa_family == AF_INET) 00614 fmt = QLatin1String("%1:%2"); 00615 #ifdef AF_INET6 00616 else if (d->addr.generic->sa_family == AF_INET6) 00617 fmt = QLatin1String("[%1]:%2"); 00618 #endif 00619 else if (d->addr.generic->sa_family == AF_UNIX) 00620 return QString(QLatin1String("unix:%1")).arg(serviceName()); 00621 else 00622 return i18nc("1: the unknown socket address family number", 00623 "Unknown family %1", d->addr.generic->sa_family); 00624 00625 return fmt.arg(nodeName()).arg(serviceName()); 00626 } 00627 00628 KInetSocketAddress& KSocketAddress::asInet() 00629 { 00630 return d->ref; 00631 } 00632 00633 KInetSocketAddress KSocketAddress::asInet() const 00634 { 00635 return d->ref; 00636 } 00637 00638 KUnixSocketAddress& KSocketAddress::asUnix() 00639 { 00640 return d->ref; 00641 } 00642 00643 KUnixSocketAddress KSocketAddress::asUnix() const 00644 { 00645 return d->ref; 00646 } 00647 00648 int KSocketAddress::ianaFamily(int af) 00649 { 00650 switch (af) 00651 { 00652 case AF_INET: 00653 return 1; 00654 00655 #ifdef AF_INET6 00656 case AF_INET6: 00657 return 2; 00658 #endif 00659 00660 default: 00661 return 0; 00662 } 00663 } 00664 00665 int KSocketAddress::fromIanaFamily(int iana) 00666 { 00667 switch (iana) 00668 { 00669 case 1: 00670 return AF_INET; 00671 00672 #ifdef AF_INET6 00673 case 2: 00674 return AF_INET6; 00675 #endif 00676 00677 default: 00678 return AF_UNSPEC; 00679 } 00680 } 00681 00682 // default constructor 00683 KInetSocketAddress::KInetSocketAddress() 00684 { 00685 } 00686 00687 // binary data constructor 00688 KInetSocketAddress::KInetSocketAddress(const sockaddr* sa, quint16 len) 00689 : KSocketAddress(sa, len) 00690 { 00691 if (!d->invalid()) 00692 update(); 00693 } 00694 00695 // create from IP and port 00696 KInetSocketAddress::KInetSocketAddress(const KIpAddress& host, quint16 port) 00697 { 00698 setHost(host); 00699 setPort(port); 00700 } 00701 00702 // copy constructor 00703 KInetSocketAddress::KInetSocketAddress(const KInetSocketAddress& other) 00704 : KSocketAddress(other) 00705 { 00706 } 00707 00708 // special copy constructor 00709 KInetSocketAddress::KInetSocketAddress(const KSocketAddress& other) 00710 : KSocketAddress(other) 00711 { 00712 if (!d->invalid()) 00713 update(); 00714 } 00715 00716 // special constructor 00717 KInetSocketAddress::KInetSocketAddress(KSocketAddressData *d) 00718 : KSocketAddress(d) 00719 { 00720 } 00721 00722 // destructor 00723 KInetSocketAddress::~KInetSocketAddress() 00724 { 00725 /* nothing to do */ 00726 } 00727 00728 // copy operator 00729 KInetSocketAddress& KInetSocketAddress::operator =(const KInetSocketAddress& other) 00730 { 00731 KSocketAddress::operator =(other); 00732 return *this; 00733 } 00734 00735 // IP version 00736 int KInetSocketAddress::ipVersion() const 00737 { 00738 if (d->invalid()) 00739 return 0; 00740 00741 switch (d->addr.generic->sa_family) 00742 { 00743 case AF_INET: 00744 return 4; 00745 00746 #ifdef AF_INET6 00747 case AF_INET6: 00748 return 6; 00749 #endif 00750 } 00751 00752 return 0; // for all other cases 00753 } 00754 00755 KIpAddress KInetSocketAddress::ipAddress() const 00756 { 00757 if (d->invalid()) 00758 return KIpAddress(); // return an empty address as well 00759 00760 switch (d->addr.generic->sa_family) 00761 { 00762 case AF_INET: 00763 return KIpAddress(&d->addr.in->sin_addr, 4); 00764 #ifdef AF_INET6 00765 case AF_INET6: 00766 return KIpAddress(&d->addr.in6->sin6_addr, 6); 00767 #endif 00768 } 00769 00770 return KIpAddress(); // empty in all other cases 00771 } 00772 00773 KInetSocketAddress& KInetSocketAddress::setHost(const KIpAddress& ip) 00774 { 00775 switch (ip.version()) 00776 { 00777 case 4: 00778 makeIPv4(); 00779 memcpy(&d->addr.in->sin_addr, ip.addr(), sizeof(d->addr.in->sin_addr)); 00780 break; 00781 00782 case 6: 00783 makeIPv6(); 00784 memcpy(&d->addr.in6->sin6_addr, ip.addr(), sizeof(d->addr.in6->sin6_addr)); 00785 break; 00786 00787 default: 00788 // empty 00789 d->invalidate(); 00790 } 00791 00792 return *this; 00793 } 00794 00795 // returns the port 00796 quint16 KInetSocketAddress::port() const 00797 { 00798 if (d->invalid()) 00799 return 0; 00800 00801 switch (d->addr.generic->sa_family) 00802 { 00803 case AF_INET: 00804 return ntohs(d->addr.in->sin_port); 00805 00806 #ifdef AF_INET6 00807 case AF_INET6: 00808 return ntohs(d->addr.in6->sin6_port); 00809 #endif 00810 } 00811 00812 return 0; 00813 } 00814 00815 KInetSocketAddress& KInetSocketAddress::setPort(quint16 port) 00816 { 00817 if (d->invalid()) 00818 makeIPv4(); 00819 00820 switch (d->addr.generic->sa_family) 00821 { 00822 case AF_INET: 00823 d->addr.in->sin_port = htons(port); 00824 break; 00825 00826 #ifdef AF_INET6 00827 case AF_INET6: 00828 d->addr.in6->sin6_port = htons(port); 00829 break; 00830 #endif 00831 00832 default: 00833 d->invalidate(); // setting the port on something else 00834 } 00835 00836 return *this; 00837 } 00838 00839 KInetSocketAddress& KInetSocketAddress::makeIPv4() 00840 { 00841 d->makeipv4(); 00842 return *this; 00843 } 00844 00845 KInetSocketAddress& KInetSocketAddress::makeIPv6() 00846 { 00847 d->makeipv6(); 00848 return *this; 00849 } 00850 00851 quint32 KInetSocketAddress::flowinfo() const 00852 { 00853 #ifndef AF_INET6 00854 return 0; 00855 #else 00856 00857 if (!d->invalid() && d->addr.in6->sin6_family == AF_INET6) 00858 return d->addr.in6->sin6_flowinfo; 00859 return 0; 00860 #endif 00861 } 00862 00863 KInetSocketAddress& KInetSocketAddress::setFlowinfo(quint32 flowinfo) 00864 { 00865 makeIPv6(); // must set here 00866 d->addr.in6->sin6_flowinfo = flowinfo; 00867 return *this; 00868 } 00869 00870 int KInetSocketAddress::scopeId() const 00871 { 00872 #ifndef AF_INET6 00873 return 0; 00874 #else 00875 00876 if (!d->invalid() && d->addr.in6->sin6_family == AF_INET6) 00877 return d->addr.in6->sin6_scope_id; 00878 return 0; 00879 #endif 00880 } 00881 00882 KInetSocketAddress& KInetSocketAddress::setScopeId(int scopeid) 00883 { 00884 makeIPv6(); // must set here 00885 d->addr.in6->sin6_scope_id = scopeid; 00886 return *this; 00887 } 00888 00889 void KInetSocketAddress::update() 00890 { 00891 if (d->addr.generic->sa_family == AF_INET) 00892 return; 00893 #ifdef AF_INET6 00894 else if (d->addr.generic->sa_family == AF_INET6) 00895 return; 00896 #endif 00897 else 00898 d->invalidate(); 00899 } 00900 00901 KUnixSocketAddress::KUnixSocketAddress() 00902 { 00903 } 00904 00905 KUnixSocketAddress::KUnixSocketAddress(const sockaddr* sa, quint16 len) 00906 : KSocketAddress(sa, len) 00907 { 00908 if (!d->invalid() && d->addr.un->sun_family != AF_UNIX) 00909 d->invalidate(); 00910 } 00911 00912 KUnixSocketAddress::KUnixSocketAddress(const KUnixSocketAddress& other) 00913 : KSocketAddress(other) 00914 { 00915 } 00916 00917 KUnixSocketAddress::KUnixSocketAddress(const QString& pathname) 00918 { 00919 setPathname(pathname); 00920 } 00921 00922 KUnixSocketAddress::KUnixSocketAddress(KSocketAddressData* d) 00923 : KSocketAddress(d) 00924 { 00925 } 00926 00927 KUnixSocketAddress::~KUnixSocketAddress() 00928 { 00929 } 00930 00931 KUnixSocketAddress& KUnixSocketAddress::operator =(const KUnixSocketAddress& other) 00932 { 00933 KSocketAddress::operator =(other); 00934 return *this; 00935 } 00936 00937 QString KUnixSocketAddress::pathname() const 00938 { 00939 if (!d->invalid() && d->addr.un->sun_family == AF_UNIX) 00940 return QFile::decodeName(d->addr.un->sun_path); 00941 return QString(); 00942 } 00943 00944 KUnixSocketAddress& KUnixSocketAddress::setPathname(const QString& path) 00945 { 00946 d->dup(0L, MIN_SOCKADDR_UN_LEN + path.length()); 00947 d->addr.un->sun_family = AF_UNIX; 00948 strcpy(d->addr.un->sun_path, QFile::encodeName(path)); 00949 00950 #ifdef HAVE_STRUCT_SOCKADDR_SA_LEN 00951 d->addr.un->sun_len = d->reallen; 00952 #endif 00953 00954 return *this; 00955 }
KDE 4.6 API Reference