kdecore Library API Documentation

ksocketaddress.cpp

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