• Skip to content
  • Skip to link menu
KDE 4.1 API Reference
  • KDE API Reference
  • kdelibs
  • Sitemap
  • Contact Us
 

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(':') != -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  
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    ((unsigned long) &(((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("%");
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 }

KDECore

Skip menu "KDECore"
  • Main Page
  • Modules
  • Namespace List
  • Class Hierarchy
  • Alphabetical List
  • Class List
  • File List
  • Namespace Members
  • Class Members
  • Related Pages

kdelibs

Skip menu "kdelibs"
  • DNSSD
  • Interfaces
  •   KHexEdit
  •   KMediaPlayer
  •   KSpeech
  •   KTextEditor
  • Kate
  • kconf_update
  • KDE3Support
  •   KUnitTest
  • KDECore
  • KDED
  • KDEsu
  • KDEUI
  • KDocTools
  • KFile
  • KHTML
  • KImgIO
  • KInit
  • KIO
  • KIOSlave
  • KJS
  •   KJS-API
  •   WTF
  • kjsembed
  • KNewStuff
  • KParts
  • Kross
  • KUtils
  • Nepomuk
  • Solid
  • Sonnet
  • ThreadWeaver
Generated for kdelibs by doxygen 1.5.4
This website is maintained by Adriaan de Groot and Allen Winter.
KDE® and the K Desktop Environment® logo are registered trademarks of KDE e.V. | Legal