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

KDECore

ksockaddr.cpp

Go to the documentation of this file.
00001 /*
00002  *  This file is part of the KDE libraries
00003  *  Copyright (C) 2000-2002 Thiago Macieira <thiago.macieira@kdemail.net>
00004  *
00005  *  This library is free software; you can redistribute it and/or
00006  *  modify it under the terms of the GNU Library General Public
00007  *  License as published by the Free Software Foundation; either
00008  *  version 2 of the License, or (at your option) any later version.
00009  *
00010  *  This library is distributed in the hope that it will be useful,
00011  *  but WITHOUT ANY WARRANTY; without even the implied warranty of
00012  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
00013  *  Library General Public License for more details.
00014  *
00015  *  You should have received a copy of the GNU Library General Public License
00016  *  along with this library; see the file COPYING.LIB.  If not, write to
00017  *  the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
00018  *  Boston, MA 02110-1301, USA.
00019  **/
00020 
00021 #include "ksockaddr.h"
00022 #include <config.h>
00023 
00024 #include <sys/types.h>
00025 
00026 #ifdef Q_OS_UNIX
00027 #include <arpa/inet.h>
00028 #endif
00029 #include <netinet/in.h>
00030 
00031 #include <limits.h>
00032 #include <stdlib.h>
00033 #include <string.h>
00034 #include <sys/un.h>
00035 #include <unistd.h>
00036 
00037 #include <qglobal.h>
00038 #include <qfile.h>
00039 
00040 #include "kdebug.h"
00041 #include "klocale.h"
00042 //#include "kextsock.h"
00043 
00044 #ifndef HAVE_STRUCT_SOCKADDR_IN6
00045 // The system doesn't have sockaddr_in6
00046 // But we can tell netsupp.h to define it for us, according to the RFC
00047 #define CLOBBER_IN6
00048 #endif
00049 
00050 #include "netsupp.h"
00051 
00052 #define V6_CAN_CONVERT_TO_V4(addr)  (KDE_IN6_IS_ADDR_V4MAPPED(addr) || KDE_IN6_IS_ADDR_V4COMPAT(addr))
00053 
00054 #ifdef HAVE_STRUCT_SOCKADDR_SA_LEN
00055 # define MY_MAX(a, b)           ((a) > (b) ? (a) : (b))
00056 # define MIN_SOCKADDR_LEN       MY_MAX(offsetof(sockaddr, sa_family) + sizeof(((sockaddr*)0)->sa_family), \
00057                            offsetof(sockaddr, sa_len) + sizeof(((sockaddr*)0)->sa_len))
00058 #else
00059 # define MIN_SOCKADDR_LEN       (offsetof(sockaddr, sa_family) + sizeof(((sockaddr*)0)->sa_family))
00060 #endif
00061 
00062 // Minimum size accepted for sockaddr_in6 sockets. 
00063 // The scopeid field is missing from some implementations
00064 // that conform to the obsoleted RFC 2133, e.g. Linux glibc 2.1
00065 #define MIN_SOCKADDR_IN6_LEN        (offsetof(sockaddr_in6, sin6_addr) + sizeof(((sockaddr_in6*)0)->sin6_addr))
00066 
00067 #ifdef offsetof
00068 #undef offsetof
00069 #endif
00070 #define offsetof(TYPE, MEMBER) ((size_t) &((TYPE *)0)->MEMBER)
00071 
00072 // This is how it is
00073 // 46 == strlen("1234:5678:9abc:def0:1234:5678:255.255.255.255")
00074 #ifndef INET6_ADDRSTRLEN
00075 #define INET6_ADDRSTRLEN        46
00076 #endif
00077 
00078 
00083 KSocketAddress::KSocketAddress(const sockaddr* sa, ksocklen_t size)
00084 {
00085     if ( !sa )
00086         init();
00087     else {
00088         data = (sockaddr*)malloc(size);
00089         if (data == NULL)
00090             return;
00091         memcpy(data, sa, size);
00092         datasize = size;
00093         owndata = true;
00094     }
00095 }
00096 
00097 void KSocketAddress::init()
00098 {
00099   data = NULL;
00100   datasize = 0;
00101   owndata = false;
00102 }
00103 
00104 KSocketAddress::~KSocketAddress()
00105 {
00106   if (owndata && data != NULL)
00107     free(data);
00108 }
00109 
00110 QString KSocketAddress::pretty() const
00111 {
00112   return i18n("<unknown socket>");
00113 }
00114 
00115 int KSocketAddress::family() const
00116 {
00117   if (data != NULL)
00118     return data->sa_family;
00119   return AF_UNSPEC;
00120 }
00121 
00122 // This creates a new KSocketAddress with given sockaddr
00123 KSocketAddress* KSocketAddress::newAddress(const struct sockaddr* sa, ksocklen_t size)
00124 {
00125   if (size == 0)
00126     {
00127       kdWarning() << "KSocketAddress::newAddress called with size = 0!\n";
00128       return NULL;
00129     }
00130 
00131   // make sure we have the right stuff
00132   if (size < MIN_SOCKADDR_LEN)
00133     {
00134       kdWarning() << "KSocketAddress::newAddress called with invalid size\n";
00135       return NULL;
00136     }
00137 
00138   switch (sa->sa_family)
00139     {
00140     case AF_INET:
00141       if (size >= sizeof(sockaddr_in))
00142     return new KInetSocketAddress((const sockaddr_in*)sa, size);
00143       return NULL;
00144 
00145 #ifdef AF_INET6
00146     case AF_INET6:
00147       if (size >= MIN_SOCKADDR_IN6_LEN)
00148     return new KInetSocketAddress((const sockaddr_in6*)sa, size);
00149       return NULL;
00150 #endif
00151 
00152     case AF_UNIX:       // AF_LOCAL
00153       return new KUnixSocketAddress((const sockaddr_un*)sa, size);
00154     }
00155 
00156   return new KSocketAddress(sa, size);
00157 }
00158 
00159 bool KSocketAddress::isEqual(const KSocketAddress& other) const
00160 {
00161   switch(family())
00162   {
00163      case AF_INET:
00164         return KInetSocketAddress::areEqualInet(*this, other, false);
00165 #ifdef AF_INET6
00166      case AF_INET6:
00167         return KInetSocketAddress::areEqualInet6(*this, other, false);
00168 #endif
00169      case AF_UNIX: // AF_LOCAL
00170         return KUnixSocketAddress::areEqualUnix(*this, other, false);
00171   }
00172 
00173   // This is not a known socket type
00174   if (other.datasize != datasize)
00175     return false;       // can't be equal
00176   return memcmp(data, other.data, datasize) == 0;
00177 }
00178 
00179 bool KSocketAddress::isCoreEqual(const KSocketAddress& other) const
00180 {
00181   switch(family())
00182   {
00183      case AF_INET:
00184         return KInetSocketAddress::areEqualInet(*this, other, true);
00185 #ifdef AF_INET6
00186      case AF_INET6:
00187         return KInetSocketAddress::areEqualInet6(*this, other, true);
00188 #endif
00189      case AF_UNIX: // AF_LOCAL
00190         return KUnixSocketAddress::areEqualUnix(*this, other, true);
00191   }
00192 
00193   return false;
00194 }
00195 
00196 QString KSocketAddress::nodeName() const
00197 {
00198   return QString::null;
00199 }
00200 
00201 QString KSocketAddress::serviceName() const
00202 {
00203   return QString::null;
00204 }
00205 
00206 int KSocketAddress::ianaFamily(int af)
00207 {
00208   switch (af)
00209     {
00210     case AF_INET:
00211       return 1;
00212 #ifdef AF_INET6
00213     case AF_INET6:
00214       return 2;
00215 #endif
00216     default:
00217       return 0;
00218     }
00219 }
00220 
00221 int KSocketAddress::fromIanaFamily(int iana)
00222 {
00223   switch (iana)
00224     {
00225     case 1:
00226       return AF_INET;
00227 #ifdef AF_INET6
00228     case 2:
00229       return AF_INET6;
00230 #endif
00231     default:
00232       return AF_UNSPEC;
00233     }
00234 }
00235 
00239 class KInetSocketAddressPrivate
00240 {
00241 public:
00242   int sockfamily;
00243   sockaddr_in sin;
00244 #ifdef AF_INET6
00245   sockaddr_in6 sin6;
00246 #endif
00247 
00248   KInetSocketAddressPrivate() :
00249     sockfamily(AF_UNSPEC)
00250   {
00251     sin.sin_family = AF_INET;
00252     sin.sin_port = 0;
00253 #ifdef HAVE_STRUCT_SOCKADDR_SA_LEN
00254     sin.sin_len = sizeof(sin);
00255 #endif
00256 #ifdef AF_INET6
00257     sin6.sin6_family = AF_INET6;
00258     sin6.sin6_port = 0;
00259     sin6.sin6_flowinfo = 0;
00260 # ifdef HAVE_STRUCT_SOCKADDR_IN6_SIN6_SCOPE_ID
00261     sin6.sin6_scope_id = 0;
00262 # endif
00263 # ifdef HAVE_STRUCT_SOCKADDR_SA_LEN
00264     sin6.sin6_len = sizeof(sin6);
00265 # endif
00266 #endif
00267   }
00268 
00269 };
00270 
00271 KInetSocketAddress::KInetSocketAddress() :
00272   d(new KInetSocketAddressPrivate)
00273 {
00274 }
00275 
00276 KInetSocketAddress::KInetSocketAddress(const KInetSocketAddress &other) :
00277   KSocketAddress(), d(new KInetSocketAddressPrivate)
00278 {
00279   setAddress(other);
00280 }
00281 
00282 KInetSocketAddress::KInetSocketAddress(const sockaddr_in* sin, ksocklen_t len) :
00283   d(new KInetSocketAddressPrivate)
00284 {
00285   setAddress(sin, len);
00286 }
00287 
00288 KInetSocketAddress::KInetSocketAddress(const sockaddr_in6* sin6, ksocklen_t len) :
00289   d(new KInetSocketAddressPrivate)
00290 {
00291   setAddress(sin6, len);
00292 }
00293 
00294 KInetSocketAddress::KInetSocketAddress(const in_addr& addr, unsigned short port) :
00295   d(new KInetSocketAddressPrivate)
00296 {
00297   setAddress(addr, port);
00298 }
00299 
00300 KInetSocketAddress::KInetSocketAddress(const in6_addr& addr, unsigned short port) :
00301   d(new KInetSocketAddressPrivate)
00302 {
00303   setAddress(addr, port);
00304 }
00305 
00306 KInetSocketAddress::KInetSocketAddress(const QString& addr, unsigned short port, int family) :
00307   d(new KInetSocketAddressPrivate)
00308 {
00309   setAddress(addr, port, family);
00310 }
00311 
00312 KInetSocketAddress::~KInetSocketAddress()
00313 {
00314   delete d;
00315 
00316   //  KSocketAddress::~KSocketAddress();
00317 }
00318 
00319 bool KInetSocketAddress::setAddress(const KInetSocketAddress &other)
00320 {
00321   if (other.family() == AF_INET)
00322     return setAddress(other.addressV4(), other.size());
00323 #ifdef AF_INET6
00324   else if (other.family() == AF_INET6)
00325     return setAddress(other.addressV6(), other.size());
00326 #endif
00327   return false;
00328 }
00329 
00330 bool KInetSocketAddress::setAddress(const sockaddr_in* sin, ksocklen_t len)
00331 {
00332   // This is supposed to be a AF_INET socket
00333   if ((len < sizeof(sockaddr_in)) || (sin->sin_family != AF_INET))
00334     {
00335       kdWarning() << "KInetSocketAddress::setAddress(sockaddr_in*) called with invalid sockaddr_in\n";
00336       return false;
00337     }
00338 
00339   return setHost(sin->sin_addr) && setPort(ntohs(sin->sin_port));
00340 }
00341 
00342 bool KInetSocketAddress::setAddress(const sockaddr_in6* sin6, ksocklen_t len)
00343 {
00344 #ifdef AF_INET6
00345   // should be family AF_INET6
00346   if ((len < MIN_SOCKADDR_IN6_LEN) || (sin6->sin6_family != AF_INET6))
00347     {
00348       kdWarning() << "KInetSocketAddress::setAddress(sockaddr_in6*) called with invalid sockaddr_in6\n";
00349       return 0;
00350     }
00351 
00352   memset(&d->sin6, 0, sizeof(d->sin6));
00353   if (len > sizeof(d->sin6))
00354     len = sizeof(d->sin6);
00355   memcpy(&d->sin6, sin6, len);
00356 
00357   /* Now make a sanity check */
00358   d->sockfamily = d->sin6.sin6_family = AF_INET6;
00359 # ifdef HAVE_STRUCT_SOCKADDR_SA_LEN
00360   d->sin6.sin6_len = sizeof(d->sin6);
00361 # endif
00362 
00363   fromV6();
00364   return true;
00365 #else  // !AF_INET6
00366   return false;
00367 #endif
00368 }
00369 
00370 bool KInetSocketAddress::setAddress(const in_addr& addr, unsigned short port)
00371 {
00372   return setHost(addr) && setPort(port);
00373 }
00374 
00375 bool KInetSocketAddress::setAddress(const in6_addr& addr, unsigned short port)
00376 {
00377   return setHost(addr) && setPort(port);
00378 }
00379 
00380 bool KInetSocketAddress::setAddress(const QString& addr, unsigned short port, int family)
00381 {
00382   return setHost(addr, family) && setPort(port);
00383 }
00384 
00385 bool KInetSocketAddress::setHost(const in_addr& addr)
00386 {
00387   d->sockfamily = AF_INET;  // set address to IPv4 type
00388   d->sin.sin_addr = addr;
00389   fromV4();
00390   return true;
00391 }
00392 
00393 bool KInetSocketAddress::setHost(const in6_addr& addr)
00394 {
00395 #ifdef AF_INET6
00396   d->sockfamily = AF_INET6; // set address to IPv6 type
00397   d->sin6.sin6_addr = addr;
00398   fromV6();
00399   return true;
00400 #else
00401   return false;
00402 #endif
00403 }
00404 
00405 bool KInetSocketAddress::setHost(const QString& addr, int family)
00406 {
00407   // if family == -1, we'll try to guess the host name
00408   if ((family != -1) && (family != AF_INET)
00409 #ifdef AF_INET6
00410       && (family != AF_INET6)
00411 #endif
00412       )
00413     {
00414       kdWarning() << "KInetSocketAddress::setHost(QString, int) called with unknown family address\n";
00415       return false;
00416     }
00417 
00418   if (family == -1)
00419     {
00420       // guess the family type
00421 
00422 #ifdef AF_INET6
00423       // IPv6 addresses MUST contain colons (:) and IPv4 addresses must not
00424       if (addr.find(':') != -1)
00425     family = AF_INET6;
00426       else
00427     family = AF_INET;
00428 #else
00429 
00430       // There's only one guess:
00431       family = AF_INET;
00432 #endif
00433     }
00434 
00435   /*
00436    * FIXME! What is the decoding process for hostnames?
00437    */
00438   if (family == AF_INET)
00439     {
00440       inet_pton(family, addr.latin1(), (void*)&(d->sin.sin_addr));
00441       fromV4();
00442     }
00443 #ifdef AF_INET6
00444   else
00445     {
00446       inet_pton(family, addr.latin1(), (void*)&(d->sin6.sin6_addr));
00447       fromV6();
00448     }
00449 #endif
00450   d->sockfamily = family;
00451   return true;
00452 }
00453 
00454 bool KInetSocketAddress::setPort(unsigned short port)
00455 {
00456   // set port on all socket types
00457   d->sin.sin_port = htons(port);
00458 #ifdef AF_INET6
00459   d->sin6.sin6_port = htons(port);
00460 #endif
00461 
00462   return true;
00463 }
00464 
00465 bool KInetSocketAddress::setFamily(int _family)
00466 {
00467   if (_family != AF_INET
00468 #ifdef AF_INET6
00469       && _family != AF_INET6
00470 #endif
00471       )
00472     {
00473       kdWarning() << "KInetSocketAddress::setFamily(int) called with unknown family\n";
00474       return false;
00475     }
00476 
00477   d->sockfamily = _family;
00478   if (_family == AF_INET)
00479     fromV4();
00480 #ifdef AF_INET6
00481   else if (_family == AF_INET6)
00482     fromV6();
00483 #endif
00484 
00485   return true;
00486 }
00487 
00488 bool KInetSocketAddress::setFlowinfo(Q_UINT32 flowinfo)
00489 {
00490 #ifdef AF_INET6
00491   if (d->sockfamily == AF_INET6)
00492     {
00493       d->sin6.sin6_flowinfo = flowinfo;
00494       return true;
00495     }
00496 #endif
00497   return false;
00498 }
00499 
00500 bool KInetSocketAddress::setScopeId(int scopeid)
00501 {
00502 #if defined(AF_INET6) && defined(HAVE_STRUCT_SOCKADDR_IN6_SIN6_SCOPE_ID)
00503   if (d->sockfamily == AF_INET6)
00504     {
00505       d->sin6.sin6_scope_id = scopeid;
00506       return true;
00507     }
00508 #endif
00509   (void)scopeid;
00510   return false;
00511 }
00512 
00513 const sockaddr_in* KInetSocketAddress::addressV4() const
00514 {
00515   if (d->sockfamily == AF_INET)
00516     return &d->sin;
00517 #ifdef AF_INET6
00518   else if (d->sockfamily == AF_INET6)
00519     {
00520       // check if this IPv6 address was converted without loss
00521       if (V6_CAN_CONVERT_TO_V4(&d->sin6.sin6_addr))
00522     return &d->sin;
00523       else
00524     return NULL;        // there was loss, so return nothing
00525     }
00526 #endif
00527 
00528   kdWarning() << "KInetSocketAddress::addressV4() called on uninitialized socket\n";
00529   return NULL;
00530 }
00531 
00532 const sockaddr_in6* KInetSocketAddress::addressV6() const
00533 {
00534 #ifdef AF_INET6
00535   return &d->sin6;
00536 #else
00537   return NULL;
00538 #endif
00539 }
00540 
00541 in_addr KInetSocketAddress::hostV4() const
00542 {
00543   // this might be empty
00544   return d->sin.sin_addr;
00545 }
00546 
00547 /*
00548  * ATTENTION
00549  * This function is left undefined if no IPv6 support exists
00550  * This is intentional
00551  */
00552 #ifdef AF_INET6
00553 in6_addr KInetSocketAddress::hostV6() const
00554 {
00555   return d->sin6.sin6_addr;
00556 }
00557 #endif
00558 
00559 QString KInetSocketAddress::pretty() const
00560 {
00561   if (d->sockfamily != AF_INET
00562 #ifdef AF_INET6
00563       && d->sockfamily != AF_INET6
00564 #endif
00565       )
00566     {
00567       kdWarning() << "KInetSocketAddress::pretty() called on uninitialized class\n";
00568       return i18n("<empty>");
00569     }
00570 
00571   return i18n("1: hostname, 2: port number", "%1 port %2").arg(nodeName()).arg(serviceName());
00572 }
00573 
00574 QString KInetSocketAddress::nodeName() const
00575 {
00576   char buf[INET6_ADDRSTRLEN];   // INET6_ADDRSTRLEN > INET_ADDRSTRLEN
00577 
00578   if (d->sockfamily == AF_INET)
00579     inet_ntop(d->sockfamily, (void*)&d->sin.sin_addr, buf, sizeof(buf));
00580 #ifdef AF_INET6
00581   else if (d->sockfamily == AF_INET6)
00582     inet_ntop(d->sockfamily, (void*)&d->sin6.sin6_addr, buf, sizeof(buf));
00583 #endif
00584   else
00585     {
00586       kdWarning() << "KInetSocketAddress::nodeName() called on uninitialized class\n";
00587       return i18n("<empty>");
00588     }
00589 
00590   return QString::fromLatin1(buf); // FIXME! What's the encoding?
00591 }
00592 
00593 QString KInetSocketAddress::serviceName() const
00594 {
00595   return QString::number(port());
00596 }
00597 
00598 unsigned short KInetSocketAddress::port() const
00599 {
00600 #ifdef AF_INET6
00601   // we prefer sin6 here because fromV6() might make sin.sin_port be 0
00602   return ntohs(d->sin6.sin6_port);
00603 #else
00604   return ntohs(d->sin.sin_port);
00605 #endif
00606 }
00607 
00608 Q_UINT32 KInetSocketAddress::flowinfo() const
00609 {
00610 #ifdef AF_INET6
00611   if (d->sockfamily == AF_INET6)
00612     return (Q_UINT32)d->sin6.sin6_flowinfo;
00613 #endif
00614   return 0;
00615 }
00616 
00617 ksocklen_t KInetSocketAddress::size() const
00618 {
00619   if (d->sockfamily == AF_INET)
00620     return sizeof(d->sin);
00621 #ifdef AF_INET6
00622   else if (d->sockfamily == AF_INET6)
00623     return sizeof(d->sin6);
00624 #endif
00625   else
00626     return 0;
00627 }
00628 
00629 bool KInetSocketAddress::areEqualInet(const KSocketAddress &s1, const KSocketAddress &s2, bool coreOnly)
00630 {
00631    if (s1.family() != s2.family())
00632       return false;
00633    if ((s1.size() < sizeof(sockaddr_in)) || (s2.size() < sizeof(sockaddr_in)))
00634       return false;
00635 
00636    struct sockaddr_in *sin1 = (sockaddr_in *) s1.address();
00637    struct sockaddr_in *sin2 = (sockaddr_in *) s2.address();
00638 
00639    if (coreOnly)
00640       return (memcmp(&sin1->sin_addr, &sin2->sin_addr, sizeof(struct in_addr))  == 0);
00641    else
00642       return (sin1->sin_port == sin2->sin_port) && 
00643              (memcmp(&sin1->sin_addr, &sin2->sin_addr, sizeof(struct in_addr))  == 0);
00644 }
00645 
00646 bool KInetSocketAddress::areEqualInet6(const KSocketAddress &s1, const KSocketAddress &s2, bool coreOnly)
00647 {
00648 #ifdef AF_INET6
00649    if (s1.family() != s2.family())
00650       return false;
00651 
00652    if ((s1.size() < sizeof(sockaddr_in6)) || (s2.size() < sizeof(sockaddr_in6)))
00653       return false;
00654 
00655    struct sockaddr_in6 *sin1 = (sockaddr_in6 *) s1.address();
00656    struct sockaddr_in6 *sin2 = (sockaddr_in6 *) s2.address();
00657 
00658    if (coreOnly)
00659      return (memcmp(&sin1->sin6_addr, &sin2->sin6_addr, sizeof(struct in6_addr))  == 0);
00660    else
00661      return (sin1->sin6_port == sin2->sin6_port) && 
00662             (sin1->sin6_flowinfo == sin2->sin6_flowinfo) && 
00663 #ifdef HAVE_STRUCT_SOCKADDR_IN6_SIN6_SCOPE_ID
00664             (sin1->sin6_scope_id == sin2->sin6_scope_id) && 
00665 #endif
00666             (memcmp(&sin1->sin6_addr, &sin2->sin6_addr, sizeof(struct in6_addr))  == 0);
00667 #else
00668    return false;
00669 #endif
00670 }
00671 
00672 void KInetSocketAddress::fromV4()
00673 {
00674   // converts an address from v4
00675 
00676 #ifdef AF_INET6
00677   d->sin6.sin6_port = d->sin.sin_port;
00678 
00679   // Make this a v4-mapped address
00680   ((Q_UINT32*)&d->sin6.sin6_addr)[0] = ((Q_UINT32*)&d->sin6.sin6_addr)[1] = 0;
00681   ((Q_UINT32*)&d->sin6.sin6_addr)[2] = htonl(0xffff);
00682   ((Q_UINT32*)&d->sin6.sin6_addr)[3] = *(Q_UINT32*)&d->sin.sin_addr;
00683 
00684   // Clear flowinfo and scopeid
00685   d->sin6.sin6_flowinfo = 0;
00686 # ifdef HAVE_STRUCT_SOCKADDR_IN6_SIN6_SCOPE_ID
00687   d->sin6.sin6_scope_id = 0;
00688 # endif
00689 #endif
00690 
00691   // data == KSocketAddress::data
00692   data = (sockaddr*)&d->sin;
00693   datasize = sizeof( sockaddr_in ); 
00694 }
00695 
00696 void KInetSocketAddress::fromV6()
00697 {
00698 #ifdef AF_INET6
00699   // convert to v4 only if this is a v4-mapped or v4-compat address
00700   if (V6_CAN_CONVERT_TO_V4(&d->sin6.sin6_addr))
00701     {
00702       d->sin.sin_port = d->sin6.sin6_port;
00703       *(Q_UINT32*)&d->sin.sin_addr = ((Q_UINT32*)&d->sin6.sin6_addr)[3];
00704     }
00705   else
00706     {
00707       d->sin.sin_port = 0;
00708       memset(&d->sin.sin_addr, 0, sizeof(d->sin.sin_addr));
00709     }
00710 
00711   data = (sockaddr*)&d->sin6;
00712   datasize = sizeof( d->sin6 );
00713 #endif
00714 }
00715 
00716 QString KInetSocketAddress::addrToString(int family, const void* addr)
00717 {
00718   char buf[INET6_ADDRSTRLEN+1];
00719 
00720   return QString::fromLatin1(inet_ntop(family, addr, buf, INET6_ADDRSTRLEN));
00721 }
00722 
00723 bool KInetSocketAddress::stringToAddr(int family, const char *text, void *dest)
00724 {
00725   return inet_pton(family, text, dest) != 0;
00726 }
00727 
00732 class KUnixSocketAddressPrivate
00733 {
00734 public:
00735   sockaddr_un *m_sun;
00736 
00737   KUnixSocketAddressPrivate() : m_sun(NULL)
00738   { }
00739 };
00740 
00741 KUnixSocketAddress::KUnixSocketAddress() :
00742   d(new KUnixSocketAddressPrivate)
00743 {
00744 }
00745 
00746 KUnixSocketAddress::KUnixSocketAddress(const sockaddr_un* _sun, ksocklen_t size) :
00747   d(new KUnixSocketAddressPrivate)
00748 {
00749   setAddress(_sun, size);
00750 }
00751 
00752 KUnixSocketAddress::KUnixSocketAddress(QCString pathname) :
00753   d(new KUnixSocketAddressPrivate)
00754 {
00755   setAddress(pathname);
00756 }
00757 
00758 KUnixSocketAddress::~KUnixSocketAddress()
00759 {
00760   delete d;
00761 }
00762 
00763 bool KUnixSocketAddress::setAddress(const sockaddr_un* _sun, ksocklen_t _size)
00764 {
00765   if (_sun->sun_family != AF_UNIX)
00766     {
00767       kdWarning() << "KUnixSocketAddress::setAddress called with invalid socket\n";
00768       return false;
00769     }
00770 
00771   if (owndata && (d->m_sun != NULL) && (datasize >= _size))
00772     {
00773       // reuse this without reallocating
00774       memcpy(d->m_sun, _sun, _size);
00775     }
00776   else
00777     {
00778       if (owndata && (d->m_sun != NULL))
00779     free(d->m_sun);
00780 
00781       d->m_sun = (sockaddr_un*)malloc(_size);
00782 
00783       if (d->m_sun == NULL)
00784     {
00785       // problems
00786       owndata = false;
00787       return false;
00788     }
00789 
00790       memcpy(d->m_sun, _sun, _size);
00791     }
00792 
00793   datasize = _size;
00794   data = (sockaddr*)d->m_sun;
00795   owndata = true;
00796 #ifdef HAVE_STRUCT_SOCKADDR_SA_LEN
00797   data->sa_len = _size;
00798 #endif
00799   return 1;
00800 }
00801 
00802 bool KUnixSocketAddress::setAddress(QCString path)
00803 {
00804   // the +1 is necessary for the ending zero
00805   ksocklen_t newsize = offsetof(sockaddr_un, sun_path) + path.length() + 1;
00806 
00807   if (owndata && (d->m_sun != NULL) && (datasize >= newsize))
00808     {
00809       // we can reuse this
00810       strcpy(d->m_sun->sun_path, path);
00811 #ifdef HAVE_STRUCT_SOCKADDR_SA_LEN
00812       data->sa_len = newsize;
00813 #endif
00814       return true;
00815     }
00816 
00817   // nah, we have to do better
00818   if (owndata && (d->m_sun != NULL))
00819     free(d->m_sun);
00820 
00821   d->m_sun = (sockaddr_un*) malloc(newsize);
00822   if (d->m_sun == NULL)
00823     {
00824       owndata = false;
00825       return false;
00826     }
00827 
00828   d->m_sun->sun_family = AF_UNIX;
00829   strcpy(d->m_sun->sun_path, path);
00830   data = (sockaddr*)d->m_sun;
00831   datasize = newsize;
00832 #ifdef HAVE_STRUCT_SOCKADDR_SA_LEN
00833   data->sa_len = newsize;
00834 #endif
00835   return 1;
00836 }
00837 
00838 QCString KUnixSocketAddress::pathname() const
00839 {
00840   if (d->m_sun != NULL)
00841     {
00842       if (datasize > offsetof(sockaddr_un, sun_path))
00843     return d->m_sun->sun_path;
00844       return "";
00845     }
00846   return QCString(0);
00847 }
00848 
00849 QString KUnixSocketAddress::pretty() const
00850 {
00851   QCString pname = pathname();
00852   if (pname.isEmpty())
00853     return i18n("<empty UNIX socket>");
00854   return QFile::decodeName(pathname());
00855 }
00856 
00857 QString KUnixSocketAddress::serviceName() const
00858 {
00859   return QString::fromUtf8(pathname());
00860 }
00861 
00862 const sockaddr_un* KUnixSocketAddress::address() const
00863 {
00864   return d->m_sun;
00865 }
00866 
00867 bool KUnixSocketAddress::areEqualUnix(const KSocketAddress &s1, const KSocketAddress &s2, bool /* coreOnly */)
00868 {
00869    if (s1.family() != s2.family())
00870       return false;   
00871 
00872    if ((s1.size() < MIN_SOCKADDR_LEN) || (s2.size() < MIN_SOCKADDR_LEN))
00873       return false;
00874 
00875    struct sockaddr_un *sun1 = (sockaddr_un *) s1.address();
00876    struct sockaddr_un *sun2 = (sockaddr_un *) s2.address();
00877 
00878    if (s1.size() == MIN_SOCKADDR_LEN && s2.size() == MIN_SOCKADDR_LEN)
00879      return true;       // unnamed Unix sockets
00880 
00881    return (strcmp(sun1->sun_path, sun2->sun_path) == 0);
00882 }
00883 
00884 void KSocketAddress::virtual_hook( int, void* )
00885 { /*BASE::virtual_hook( id, data );*/ }
00886 
00887 void KInetSocketAddress::virtual_hook( int id, void* data )
00888 { KSocketAddress::virtual_hook( id, data ); }
00889 
00890 void KUnixSocketAddress::virtual_hook( int id, void* data )
00891 { KSocketAddress::virtual_hook( id, data ); }
00892 
00893 
00894 #include "ksockaddr.moc"

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