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