kdecore Library API Documentation

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 }
KDE Logo
This file is part of the documentation for kdecore Library Version 3.4.2.
Documentation copyright © 1996-2004 the KDE developers.
Generated on Thu Sep 15 10:19:39 2005 by doxygen 1.4.4 written by Dimitri van Heesch, © 1997-2003