kdecore Library: ksocketaddress.cpp Source File (kdecore Library)

| # kdecore Library API Documentation
Overview | Class Hierarchy | Classes | Classes (annotated) | Members | Namespaces | Source Files

# ksocketaddress.cpp

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

This file is part of the documentation for kdecore Library Version 3.4.1.
Documentation copyright © 1996-2004 the KDE developers.
Generated on Sat Jun 11 20:18:10 2005 by doxygen 1.4.1 written by Dimitri van Heesch, © 1997-2003