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 "klocale.h"
00040 #include "ksocketaddress.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 Q_UINT32* v6addr, Q_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 QString& 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       Q_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       Q_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(QString::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 QString 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 QString::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 QString::fromLatin1(buf);
00204     }
00205 
00206   return QString::null;
00207 }
00208 
00209 /*
00210  * An IPv6 socket address
00211  * This is taken from RFC 2553.
00212  */
00213 struct our_sockaddr_in6
00214 {
00215 # ifdef HAVE_STRUCT_SOCKADDR_SA_LEN
00216   Q_UINT8       sin6_len;
00217   Q_UINT8       sin6_family;
00218 # else  
00219   Q_UINT16      sin6_family;
00220 # endif
00221   Q_UINT16          sin6_port;  /* RFC says in_port_t */
00222   Q_UINT32      sin6_flowinfo;
00223   Q_UINT8       sin6_addr[16]; // 24 bytes up to here
00224   Q_UINT32      sin6_scope_id; // 28 bytes total
00225 };
00226 
00227 // useful definitions
00228 #define MIN_SOCKADDR_LEN    sizeof(Q_UINT16)
00229 #define SOCKADDR_IN_LEN     sizeof(sockaddr_in)
00230 #define MIN_SOCKADDR_IN6_LEN    ((unsigned long) &(((our_sockaddr_in6*)0)->sin6_scope_id))
00231 #define SOCKADDR_IN6_LEN    sizeof(our_sockaddr_in6)
00232 #define MIN_SOCKADDR_UN_LEN (sizeof(Q_UINT16) + sizeof(char))
00233 
00234 
00235 class KNetwork::KSocketAddressData
00236 {
00237 public:
00238   /*
00239    * Note: maybe this should be virtual
00240    * But since the data is shared via the d pointer, it doesn't really matter
00241    * what one class sees, so will the other
00242    */
00243   class QMixSocketAddressRef : public KInetSocketAddress, public KUnixSocketAddress
00244   {
00245   public:
00246     QMixSocketAddressRef(KSocketAddressData* d)
00247       : KInetSocketAddress(d), KUnixSocketAddress(d)
00248     {
00249     }
00250   };
00251   QMixSocketAddressRef ref;
00252 
00253   union
00254   {
00255     struct sockaddr         *generic;
00256     struct sockaddr_in      *in;
00257     struct our_sockaddr_in6 *in6;
00258     struct sockaddr_un      *un;
00259   } addr;
00260   Q_UINT16 curlen, reallen;
00261 
00262   KSocketAddressData()
00263     : ref(this)
00264   {
00265     addr.generic = 0L;
00266     curlen = 0;
00267     invalidate();
00268   }
00269 
00270   ~KSocketAddressData()
00271   {
00272     if (addr.generic != 0L)
00273       free(addr.generic);
00274   }
00275 
00276   inline bool invalid() const
00277   { return reallen == 0; }
00278 
00279   inline void invalidate()
00280   { reallen = 0; }
00281 
00282   void dup(const sockaddr* sa, Q_UINT16 len, bool clear = true);
00283 
00284   void makeipv4()
00285   {
00286     short oldport = 0;
00287     if (!invalid())
00288       switch (addr.generic->sa_family)
00289     {
00290     case AF_INET:
00291       return;       // nothing to do here
00292 #ifdef AF_INET6
00293     case AF_INET6:
00294       oldport = addr.in6->sin6_port;
00295       break;
00296 #endif
00297     }
00298 
00299     // create new space
00300     dup(0L, SOCKADDR_IN_LEN);
00301 
00302     addr.in->sin_family = AF_INET;
00303 #ifdef HAVE_STRUCT_SOCKADDR_SA_LEN
00304     addr.in->sin_len = SOCKADDR_IN_LEN;
00305 #endif
00306     addr.in->sin_port = oldport;
00307   }
00308 
00309   void makeipv6()
00310   {
00311     short oldport = 0;
00312     if (!invalid())
00313       switch (addr.generic->sa_family)
00314     {
00315     case AF_INET:
00316       oldport = addr.in->sin_port;
00317       break;
00318 
00319 #ifdef AF_INET6
00320     case AF_INET6:
00321       return;       // nothing to do here
00322 #endif
00323     }
00324 
00325     // make room
00326     dup(0L, SOCKADDR_IN6_LEN);
00327 #ifdef AF_INET6
00328     addr.in6->sin6_family = AF_INET6;
00329 #endif
00330 #ifdef HAVE_STRUCT_SOCKADDR_SA_LEN
00331     addr.in6->sin6_len = SOCKADDR_IN6_LEN;
00332 #endif
00333     addr.in6->sin6_port = oldport;
00334     // sin6_scope_id and sin6_flowid are zero
00335   }
00336 
00337 };
00338 
00339 // create duplicates of
00340 void KSocketAddressData::dup(const sockaddr* sa, Q_UINT16 len, bool clear)
00341 {
00342   if (len < MIN_SOCKADDR_LEN)
00343     {
00344       // certainly invalid
00345       invalidate();
00346       return;
00347     }
00348 
00349   if (sa && ((sa->sa_family == AF_INET && len < SOCKADDR_IN_LEN) ||
00350 #ifdef AF_INET6
00351          (sa->sa_family == AF_INET6 && len < MIN_SOCKADDR_IN6_LEN) ||
00352 #endif
00353          (sa->sa_family == AF_UNIX && len < MIN_SOCKADDR_UN_LEN)))
00354     {
00355       // also invalid
00356       invalidate();
00357       return;
00358     }
00359 
00360   // good
00361   reallen = len;
00362   if (len > curlen)
00363     {
00364       if (len < 32)
00365     curlen = 32;        // big enough for sockaddr_in and sockaddr_in6
00366       else
00367     curlen = len;
00368       addr.generic = (sockaddr*)realloc(addr.generic, curlen);
00369     }
00370 
00371   if (sa != 0L)
00372     {
00373       memcpy(addr.generic, sa, len); // copy
00374 
00375       // now, normalise the data
00376       if (addr.generic->sa_family == AF_INET)
00377     reallen = SOCKADDR_IN_LEN; // no need to be larger
00378 #ifdef AF_INET6
00379       else if (addr.generic->sa_family == AF_INET6)
00380     {
00381       // set the extra field (sin6_scope_id)
00382       
00383       // the buffer is never smaller than 32 bytes, so this is always
00384       // allowed
00385       if (reallen < SOCKADDR_IN6_LEN)
00386         addr.in6->sin6_scope_id = 0;
00387       
00388       reallen = SOCKADDR_IN6_LEN;
00389     }
00390 #endif
00391       else if (addr.generic->sa_family == AF_UNIX)
00392     reallen = MIN_SOCKADDR_UN_LEN + strlen(addr.un->sun_path);
00393     }
00394   else if (clear)
00395     {
00396       memset(addr.generic, 0, len);
00397       addr.generic->sa_family = AF_UNSPEC;
00398     }
00399 }
00400 
00401 // default constructor
00402 KSocketAddress::KSocketAddress()
00403   : d(new KSocketAddressData)
00404 {
00405 }
00406 
00407 // constructor from binary data
00408 KSocketAddress::KSocketAddress(const sockaddr *sa, Q_UINT16 len)
00409   : d(new KSocketAddressData)
00410 {
00411   setAddress(sa, len);
00412 }
00413 
00414 KSocketAddress::KSocketAddress(const KSocketAddress& other)
00415   : d(new(KSocketAddressData))
00416 {
00417   *this = other;
00418 }
00419 
00420 KSocketAddress::KSocketAddress(KSocketAddressData *d2)
00421   : d(d2)
00422 {
00423 }
00424 
00425 KSocketAddress::~KSocketAddress()
00426 {
00427   // prevent double-deletion, since we're already being deleted
00428   if (d)
00429     {
00430       d->ref.KInetSocketAddress::d = 0L;
00431       d->ref.KUnixSocketAddress::d = 0L;
00432       delete d;
00433     }
00434 }
00435 
00436 KSocketAddress& KSocketAddress::operator =(const KSocketAddress& other)
00437 {
00438   if (other.d && !other.d->invalid())
00439     d->dup(other.d->addr.generic, other.d->reallen);
00440   else
00441     d->invalidate();
00442   return *this;
00443 }
00444 
00445 const sockaddr* KSocketAddress::address() const
00446 {
00447   if (d->invalid())
00448     return 0L;
00449   return d->addr.generic;
00450 }
00451 
00452 sockaddr* KSocketAddress::address()
00453 {
00454   if (d->invalid())
00455     return 0L;
00456   return d->addr.generic;
00457 }
00458 
00459 KSocketAddress& KSocketAddress::setAddress(const sockaddr* sa, Q_UINT16 len)
00460 {
00461   if (sa != 0L && len >= MIN_SOCKADDR_LEN)
00462     d->dup(sa, len);
00463   else
00464     d->invalidate();
00465 
00466   return *this;
00467 }
00468 
00469 Q_UINT16 KSocketAddress::length() const
00470 {
00471   if (d->invalid())
00472     return 0;
00473   return d->reallen;
00474 }
00475 
00476 KSocketAddress& KSocketAddress::setLength(Q_UINT16 len)
00477 {
00478   d->dup((sockaddr*)0L, len, false);
00479 
00480   return *this;
00481 }
00482 
00483 int KSocketAddress::family() const
00484 {
00485   if (d->invalid())
00486     return AF_UNSPEC;
00487   return d->addr.generic->sa_family;
00488 }
00489 
00490 KSocketAddress& KSocketAddress::setFamily(int family)
00491 {
00492   if (d->invalid())
00493     d->dup((sockaddr*)0L, MIN_SOCKADDR_LEN);
00494   d->addr.generic->sa_family = family;
00495 
00496   return *this;
00497 }
00498 
00499 bool KSocketAddress::operator ==(const KSocketAddress& other) const
00500 {
00501   // if this is invalid, it's only equal if the other one is invalid as well
00502   if (d->invalid())
00503     return other.d->invalid();
00504 
00505   // check the family to make sure we don't do unnecessary comparison
00506   if (d->addr.generic->sa_family != other.d->addr.generic->sa_family)
00507     return false;       // not the same family, not equal
00508 
00509   // same family then
00510   // check the ones we know already
00511   switch (d->addr.generic->sa_family)
00512     {
00513     case AF_INET:
00514       Q_ASSERT(d->reallen == SOCKADDR_IN_LEN);
00515       Q_ASSERT(other.d->reallen == SOCKADDR_IN_LEN);
00516       return memcmp(d->addr.in, other.d->addr.in, SOCKADDR_IN_LEN) == 0;
00517 
00518 #ifdef AF_INET6
00519     case AF_INET6:
00520       Q_ASSERT(d->reallen >= MIN_SOCKADDR_IN6_LEN);
00521       Q_ASSERT(other.d->reallen >= MIN_SOCKADDR_IN6_LEN);
00522 
00523 # if !defined(HAVE_STRUCT_SOCKADDR_IN6) || defined(HAVE_STRUCT_SOCKADDR_IN6_SIN6_SCOPE_ID)
00524       // check for the case where sin6_scope_id isn't present
00525       if (d->reallen != other.d->reallen)
00526     {
00527       if (memcmp(d->addr.in6, other.d->addr.in6, MIN_SOCKADDR_IN6_LEN) != 0)
00528         return false;   // not equal
00529       if (d->reallen > other.d->reallen)
00530         return d->addr.in6->sin6_scope_id == 0;
00531       else
00532         return other.d->addr.in6->sin6_scope_id == 0;
00533     }
00534 # endif
00535 
00536     return memcmp(d->addr.in6, other.d->addr.in6, d->reallen) == 0;
00537 #endif
00538 
00539     case AF_UNIX:
00540       Q_ASSERT(d->reallen >= MIN_SOCKADDR_UN_LEN);
00541       Q_ASSERT(other.d->reallen >= MIN_SOCKADDR_UN_LEN);
00542 
00543       // do a string comparison here
00544       return strcmp(d->addr.un->sun_path, other.d->addr.un->sun_path) == 0;
00545 
00546     default:
00547       // something else we don't know about
00548       // they are equal if and only if they are exactly equal
00549       if (d->reallen == other.d->reallen)
00550     return memcmp(d->addr.generic, other.d->addr.generic, d->reallen) == 0;
00551     }
00552 
00553   return false;     // not equal in any other case
00554 }
00555 
00556 QString KSocketAddress::nodeName() const
00557 {
00558   if (d->invalid())
00559     return QString::null;
00560 
00561   switch (d->addr.generic->sa_family)
00562     {
00563     case AF_INET:
00564 #ifdef AF_INET6
00565     case AF_INET6:
00566 
00567       QString scopeid("%");
00568       if (d->addr.generic->sa_family == AF_INET6 && d->addr.in6->sin6_scope_id)
00569     scopeid += QString::number(d->addr.in6->sin6_scope_id);
00570       else
00571     scopeid.truncate(0);
00572       return d->ref.ipAddress().toString() + scopeid;
00573 #else
00574       return d->ref.ipAddress().toString();
00575 #endif
00576     }
00577 
00578   // any other case, including AF_UNIX
00579   return QString::null;
00580 }
00581 
00582 QString KSocketAddress::serviceName() const
00583 {
00584   if (d->invalid())
00585     return QString::null;
00586 
00587   switch (d->addr.generic->sa_family)
00588     {
00589     case AF_INET:
00590 #ifdef AF_INET6
00591     case AF_INET6:
00592 #endif
00593       return QString::number(d->ref.port());
00594 
00595     case AF_UNIX:
00596       return d->ref.pathname();
00597     }
00598 
00599   return QString::null;
00600 }
00601 
00602 QString KSocketAddress::toString() const
00603 {
00604   if (d->invalid())
00605     return QString::null;
00606 
00607   QString fmt;
00608 
00609   if (d->addr.generic->sa_family == AF_INET)
00610     fmt = "%1:%2";
00611 #ifdef AF_INET6
00612   else if (d->addr.generic->sa_family == AF_INET6)
00613     fmt = "[%1]:%2";
00614 #endif
00615   else if (d->addr.generic->sa_family == AF_UNIX)
00616     return QString::fromLatin1("unix:%1").arg(serviceName());
00617   else
00618     return i18n("1: the unknown socket address family number",
00619         "Unknown family %1").arg(d->addr.generic->sa_family);
00620 
00621   return fmt.arg(nodeName()).arg(serviceName());
00622 }
00623 
00624 KInetSocketAddress& KSocketAddress::asInet()
00625 {
00626   return d->ref;
00627 }
00628 
00629 KInetSocketAddress KSocketAddress::asInet() const
00630 {
00631   return d->ref;
00632 }
00633 
00634 KUnixSocketAddress& KSocketAddress::asUnix()
00635 {
00636   return d->ref;
00637 }
00638 
00639 KUnixSocketAddress KSocketAddress::asUnix() const
00640 {
00641   return d->ref;
00642 }
00643 
00644 int KSocketAddress::ianaFamily(int af)
00645 {
00646   switch (af)
00647     {
00648     case AF_INET:
00649       return 1;
00650 
00651 #ifdef AF_INET6
00652     case AF_INET6:
00653       return 2;
00654 #endif
00655 
00656     default:
00657       return 0;
00658     }
00659 }
00660 
00661 int KSocketAddress::fromIanaFamily(int iana)
00662 {
00663   switch (iana)
00664     {
00665     case 1:
00666       return AF_INET;
00667 
00668 #ifdef AF_INET6
00669     case 2:
00670       return AF_INET6;
00671 #endif
00672 
00673     default:
00674       return AF_UNSPEC;
00675     }
00676 }
00677 
00678 // default constructor
00679 KInetSocketAddress::KInetSocketAddress()
00680 {
00681 }
00682 
00683 // binary data constructor
00684 KInetSocketAddress::KInetSocketAddress(const sockaddr* sa, Q_UINT16 len)
00685   : KSocketAddress(sa, len)
00686 {
00687   if (!d->invalid())
00688     update();
00689 }
00690 
00691 // create from IP and port
00692 KInetSocketAddress::KInetSocketAddress(const KIpAddress& host, Q_UINT16 port)
00693 {
00694   setHost(host);
00695   setPort(port);
00696 }
00697 
00698 // copy constructor
00699 KInetSocketAddress::KInetSocketAddress(const KInetSocketAddress& other)
00700   : KSocketAddress(other)
00701 {
00702 }
00703 
00704 // special copy constructor
00705 KInetSocketAddress::KInetSocketAddress(const KSocketAddress& other)
00706   : KSocketAddress(other)
00707 {
00708   if (!d->invalid())
00709     update();
00710 }
00711 
00712 // special constructor
00713 KInetSocketAddress::KInetSocketAddress(KSocketAddressData *d)
00714   : KSocketAddress(d)
00715 {
00716 }
00717 
00718 // destructor
00719 KInetSocketAddress::~KInetSocketAddress()
00720 {
00721   /* nothing to do */
00722 }
00723 
00724 // copy operator
00725 KInetSocketAddress& KInetSocketAddress::operator =(const KInetSocketAddress& other)
00726 {
00727   KSocketAddress::operator =(other);
00728   return *this;
00729 }
00730 
00731 // IP version
00732 int KInetSocketAddress::ipVersion() const
00733 {
00734   if (d->invalid())
00735     return 0;
00736 
00737   switch (d->addr.generic->sa_family)
00738     {
00739     case AF_INET:
00740       return 4;
00741 
00742 #ifdef AF_INET6
00743     case AF_INET6:
00744       return 6;
00745 #endif
00746     }
00747 
00748   return 0;         // for all other cases
00749 }
00750 
00751 KIpAddress KInetSocketAddress::ipAddress() const
00752 {
00753   if (d->invalid())
00754     return KIpAddress();    // return an empty address as well
00755 
00756   switch (d->addr.generic->sa_family)
00757     {
00758     case AF_INET:
00759       return KIpAddress(&d->addr.in->sin_addr, 4);
00760 #ifdef AF_INET6
00761     case AF_INET6:
00762       return KIpAddress(&d->addr.in6->sin6_addr, 6);
00763 #endif
00764     }
00765 
00766   return KIpAddress();      // empty in all other cases
00767 }
00768 
00769 KInetSocketAddress& KInetSocketAddress::setHost(const KIpAddress& ip)
00770 {
00771   switch (ip.version())
00772     {
00773     case 4:
00774       makeIPv4();
00775       memcpy(&d->addr.in->sin_addr, ip.addr(), sizeof(d->addr.in->sin_addr));
00776       break;
00777 
00778     case 6:
00779       makeIPv6();
00780       memcpy(&d->addr.in6->sin6_addr, ip.addr(), sizeof(d->addr.in6->sin6_addr));
00781       break;
00782 
00783     default:
00784       // empty
00785       d->invalidate();
00786     }
00787 
00788   return *this;
00789 }
00790 
00791 // returns the port
00792 Q_UINT16 KInetSocketAddress::port() const
00793 {
00794   if (d->invalid())
00795     return 0;
00796 
00797   switch (d->addr.generic->sa_family)
00798     {
00799     case AF_INET:
00800       return ntohs(d->addr.in->sin_port);
00801 
00802 #ifdef AF_INET6
00803     case AF_INET6:
00804       return ntohs(d->addr.in6->sin6_port);
00805 #endif
00806     }
00807 
00808   return 0;
00809 }
00810 
00811 KInetSocketAddress& KInetSocketAddress::setPort(Q_UINT16 port)
00812 {
00813   if (d->invalid())
00814     makeIPv4();
00815 
00816   switch (d->addr.generic->sa_family)
00817     {
00818     case AF_INET:
00819       d->addr.in->sin_port = htons(port);
00820       break;
00821       
00822 #ifdef AF_INET6
00823     case AF_INET6:
00824       d->addr.in6->sin6_port = htons(port);
00825       break;
00826 #endif
00827       
00828     default:
00829       d->invalidate();      // setting the port on something else
00830     }
00831 
00832   return *this;
00833 }
00834 
00835 KInetSocketAddress& KInetSocketAddress::makeIPv4()
00836 {
00837   d->makeipv4();
00838   return *this;
00839 }
00840 
00841 KInetSocketAddress& KInetSocketAddress::makeIPv6()
00842 {
00843   d->makeipv6();
00844   return *this;
00845 }
00846 
00847 Q_UINT32 KInetSocketAddress::flowinfo() const
00848 {
00849 #ifndef AF_INET6
00850   return 0;
00851 #else
00852 
00853   if (!d->invalid() && d->addr.in6->sin6_family == AF_INET6)
00854     return d->addr.in6->sin6_flowinfo;
00855   return 0;
00856 #endif
00857 }
00858 
00859 KInetSocketAddress& KInetSocketAddress::setFlowinfo(Q_UINT32 flowinfo)
00860 {
00861   makeIPv6();           // must set here
00862   d->addr.in6->sin6_flowinfo = flowinfo;
00863   return *this;
00864 }
00865 
00866 int KInetSocketAddress::scopeId() const
00867 {
00868 #ifndef AF_INET6
00869   return 0;
00870 #else
00871 
00872   if (!d->invalid() && d->addr.in6->sin6_family == AF_INET6)
00873     return d->addr.in6->sin6_scope_id;
00874   return 0;
00875 #endif
00876 }
00877 
00878 KInetSocketAddress& KInetSocketAddress::setScopeId(int scopeid)
00879 {
00880   makeIPv6();           // must set here
00881   d->addr.in6->sin6_scope_id = scopeid;
00882   return *this;
00883 }
00884 
00885 void KInetSocketAddress::update()
00886 {
00887   if (d->addr.generic->sa_family == AF_INET)
00888     return;
00889 #ifdef AF_INET6
00890   else if (d->addr.generic->sa_family == AF_INET6)
00891     return;
00892 #endif
00893   else
00894     d->invalidate();
00895 }
00896 
00897 KUnixSocketAddress::KUnixSocketAddress()
00898 {
00899 }
00900 
00901 KUnixSocketAddress::KUnixSocketAddress(const sockaddr* sa, Q_UINT16 len)
00902   : KSocketAddress(sa, len)
00903 {
00904   if (!d->invalid() && d->addr.un->sun_family != AF_UNIX)
00905     d->invalidate();
00906 }
00907 
00908 KUnixSocketAddress::KUnixSocketAddress(const KUnixSocketAddress& other)
00909   : KSocketAddress(other)
00910 {
00911 }
00912 
00913 KUnixSocketAddress::KUnixSocketAddress(const QString& pathname)
00914 {
00915   setPathname(pathname);
00916 }
00917 
00918 KUnixSocketAddress::KUnixSocketAddress(KSocketAddressData* d)
00919   : KSocketAddress(d)
00920 {
00921 }
00922 
00923 KUnixSocketAddress::~KUnixSocketAddress()
00924 {
00925 }
00926 
00927 KUnixSocketAddress& KUnixSocketAddress::operator =(const KUnixSocketAddress& other)
00928 {
00929   KSocketAddress::operator =(other);
00930   return *this;
00931 }
00932 
00933 QString KUnixSocketAddress::pathname() const
00934 {
00935   if (!d->invalid() && d->addr.un->sun_family == AF_UNIX)
00936     return QFile::decodeName(d->addr.un->sun_path);
00937   return QString::null;
00938 }
00939 
00940 KUnixSocketAddress& KUnixSocketAddress::setPathname(const QString& path)
00941 {
00942   d->dup(0L, MIN_SOCKADDR_UN_LEN + path.length());
00943   d->addr.un->sun_family = AF_UNIX;
00944   strcpy(d->addr.un->sun_path, QFile::encodeName(path));
00945 
00946 #ifdef HAVE_STRUCT_SOCKADDR_SA_LEN
00947   d->addr.un->sun_len = d->reallen;
00948 #endif
00949 
00950   return *this;
00951 }
KDE Home | KDE Accessibility Home | Description of Access Keys