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

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

# ksockaddr.cpp

    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., 59 Temple Place - Suite 330,
    00018  *  Boston, MA 02111-1307, 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"

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