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

KDECore

ksocketaddress.cpp

Go to the documentation of this file.
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 Q_UINT32 KIpAddress::hostIPv4Addr(bool convertMapped) const
00210 {
00211     Q_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   Q_UINT8       sin6_len;
00223   Q_UINT8       sin6_family;
00224 # else  
00225   Q_UINT16      sin6_family;
00226 # endif
00227   Q_UINT16          sin6_port;  /* RFC says in_port_t */
00228   Q_UINT32      sin6_flowinfo;
00229   Q_UINT8       sin6_addr[16]; // 24 bytes up to here
00230   Q_UINT32      sin6_scope_id; // 28 bytes total
00231 };
00232 
00233 // useful definitions
00234 #define MIN_SOCKADDR_LEN    sizeof(Q_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(Q_UINT16) + sizeof(char))
00239 
00240 
00241 class KNetwork::KSocketAddressData
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(KSocketAddressData* 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   Q_UINT16 curlen, reallen;
00267 
00268   KSocketAddressData()
00269     : ref(this)
00270   {
00271     addr.generic = 0L;
00272     curlen = 0;
00273     invalidate();
00274   }
00275 
00276   ~KSocketAddressData()
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, Q_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 KSocketAddressData::dup(const sockaddr* sa, Q_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 KSocketAddress::KSocketAddress()
00409   : d(new KSocketAddressData)
00410 {
00411 }
00412 
00413 // constructor from binary data
00414 KSocketAddress::KSocketAddress(const sockaddr *sa, Q_UINT16 len)
00415   : d(new KSocketAddressData)
00416 {
00417   setAddress(sa, len);
00418 }
00419 
00420 KSocketAddress::KSocketAddress(const KSocketAddress& other)
00421   : d(new(KSocketAddressData))
00422 {
00423   *this = other;
00424 }
00425 
00426 KSocketAddress::KSocketAddress(KSocketAddressData *d2)
00427   : d(d2)
00428 {
00429 }
00430 
00431 KSocketAddress::~KSocketAddress()
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 KSocketAddress& KSocketAddress::operator =(const KSocketAddress& 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* KSocketAddress::address() const
00452 {
00453   if (d->invalid())
00454     return 0L;
00455   return d->addr.generic;
00456 }
00457 
00458 sockaddr* KSocketAddress::address()
00459 {
00460   if (d->invalid())
00461     return 0L;
00462   return d->addr.generic;
00463 }
00464 
00465 KSocketAddress& KSocketAddress::setAddress(const sockaddr* sa, Q_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 Q_UINT16 KSocketAddress::length() const
00476 {
00477   if (d->invalid())
00478     return 0;
00479   return d->reallen;
00480 }
00481 
00482 KSocketAddress& KSocketAddress::setLength(Q_UINT16 len)
00483 {
00484   d->dup((sockaddr*)0L, len, false);
00485 
00486   return *this;
00487 }
00488 
00489 int KSocketAddress::family() const
00490 {
00491   if (d->invalid())
00492     return AF_UNSPEC;
00493   return d->addr.generic->sa_family;
00494 }
00495 
00496 KSocketAddress& KSocketAddress::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 KSocketAddress::operator ==(const KSocketAddress& 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 QString KSocketAddress::nodeName() const
00563 {
00564   if (d->invalid())
00565     return QString::null;
00566 
00567   switch (d->addr.generic->sa_family)
00568     {
00569     case AF_INET:
00570 #ifdef AF_INET6
00571     case AF_INET6:
00572 
00573       QString scopeid("%");
00574       if (d->addr.generic->sa_family == AF_INET6 && d->addr.in6->sin6_scope_id)
00575     scopeid += QString::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 QString::null;
00586 }
00587 
00588 QString KSocketAddress::serviceName() const
00589 {
00590   if (d->invalid())
00591     return QString::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 QString::number(d->ref.port());
00600 
00601     case AF_UNIX:
00602       return d->ref.pathname();
00603     }
00604 
00605   return QString::null;
00606 }
00607 
00608 QString KSocketAddress::toString() const
00609 {
00610   if (d->invalid())
00611     return QString::null;
00612 
00613   QString 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 QString::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& KSocketAddress::asInet()
00631 {
00632   return d->ref;
00633 }
00634 
00635 KInetSocketAddress KSocketAddress::asInet() const
00636 {
00637   return d->ref;
00638 }
00639 
00640 KUnixSocketAddress& KSocketAddress::asUnix()
00641 {
00642   return d->ref;
00643 }
00644 
00645 KUnixSocketAddress KSocketAddress::asUnix() const
00646 {
00647   return d->ref;
00648 }
00649 
00650 int KSocketAddress::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 KSocketAddress::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, Q_UINT16 len)
00691   : KSocketAddress(sa, len)
00692 {
00693   if (!d->invalid())
00694     update();
00695 }
00696 
00697 // create from IP and port
00698 KInetSocketAddress::KInetSocketAddress(const KIpAddress& host, Q_UINT16 port)
00699 {
00700   setHost(host);
00701   setPort(port);
00702 }
00703 
00704 // copy constructor
00705 KInetSocketAddress::KInetSocketAddress(const KInetSocketAddress& other)
00706   : KSocketAddress(other)
00707 {
00708 }
00709 
00710 // special copy constructor
00711 KInetSocketAddress::KInetSocketAddress(const KSocketAddress& other)
00712   : KSocketAddress(other)
00713 {
00714   if (!d->invalid())
00715     update();
00716 }
00717 
00718 // special constructor
00719 KInetSocketAddress::KInetSocketAddress(KSocketAddressData *d)
00720   : KSocketAddress(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   KSocketAddress::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 Q_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(Q_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 Q_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(Q_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, Q_UINT16 len)
00908   : KSocketAddress(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   : KSocketAddress(other)
00916 {
00917 }
00918 
00919 KUnixSocketAddress::KUnixSocketAddress(const QString& pathname)
00920 {
00921   setPathname(pathname);
00922 }
00923 
00924 KUnixSocketAddress::KUnixSocketAddress(KSocketAddressData* d)
00925   : KSocketAddress(d)
00926 {
00927 }
00928 
00929 KUnixSocketAddress::~KUnixSocketAddress()
00930 {
00931 }
00932 
00933 KUnixSocketAddress& KUnixSocketAddress::operator =(const KUnixSocketAddress& other)
00934 {
00935   KSocketAddress::operator =(other);
00936   return *this;
00937 }
00938 
00939 QString KUnixSocketAddress::pathname() const
00940 {
00941   if (!d->invalid() && d->addr.un->sun_family == AF_UNIX)
00942     return QFile::decodeName(d->addr.un->sun_path);
00943   return QString::null;
00944 }
00945 
00946 KUnixSocketAddress& KUnixSocketAddress::setPathname(const QString& 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, QFile::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 }

KDECore

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

API Reference

Skip menu "API Reference"
  • dcop
  • DNSSD
  • interfaces
  • Kate
  • kconf_update
  • KDECore
  • KDED
  • kdefx
  • KDEsu
  • kdeui
  • KDocTools
  • KHTML
  • KImgIO
  • KInit
  • kio
  • kioslave
  • KJS
  • KNewStuff
  • KParts
  • KUtils
Generated for API Reference by doxygen 1.5.9
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