27 #include <sys/types.h>
28 #include <sys/socket.h>
30 #include <arpa/inet.h>
31 #include <netinet/in.h>
40 #include "tdesocketaddress.h"
44 using namespace KNetwork;
47 class KIpAddress_localhostV4 :
public KIpAddress
50 KIpAddress_localhostV4()
52 *m_data = htonl(0x7f000001);
57 class KIpAddress_localhostV6 :
public KIpAddress
60 KIpAddress_localhostV6()
68 static const char localhostV4_data[] = { 127, 0, 0, 1 };
69 static const char localhostV6_data[] = { 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,1 };
77 static bool check_v4mapped(
const TQ_UINT32* v6addr, TQ_UINT32 v4addr)
80 if (!(v6addr[0] == 0 && v6addr[1] == 0 && v6addr[2] == htonl(0x0000ffff)))
83 return v6addr[3] == v4addr;
89 m_version = other.m_version;
90 if (m_version == 4 || m_version == 6)
91 memcpy(m_data, other.m_data,
sizeof(m_data));
98 if (m_version == other.m_version)
107 return *m_data == *other.m_data;
112 return memcmp(m_data, other.m_data, 16) == 0;
118 if (m_version == 6 && other.m_version == 4 && check_v4mapped(m_data, *other.m_data))
121 if (other.m_version == 6 && m_version == 4 && check_v4mapped(other.m_data, *m_data))
134 if (address.find(
':') != -1)
140 if (inet_pton(AF_INET6, address.latin1(), buf))
142 memcpy(m_data, buf,
sizeof(m_data));
153 if (inet_pton(AF_INET, address.latin1(), &buf))
168 return setAddress(TQString::fromLatin1(address));
176 if (version != 4 && version != 6)
181 memcpy(m_data, raw, version == 4 ? 4 : 16);
183 memset(m_data, 0, 16);
191 char buf[
sizeof "1111:2222:3333:4444:5555:6666:255.255.255.255" + 2];
196 inet_ntop(AF_INET, m_data, buf,
sizeof(buf) - 1);
197 return TQString::fromLatin1(buf);
202 inet_ntop(AF_INET6, m_data, buf,
sizeof(buf) - 1);
204 return TQString::fromLatin1(buf);
208 return TQString::null;
221 struct our_sockaddr_in6
223 # ifdef HAVE_STRUCT_SOCKADDR_SA_LEN
225 TQ_UINT8 sin6_family;
227 TQ_UINT16 sin6_family;
230 TQ_UINT32 sin6_flowinfo;
231 TQ_UINT8 sin6_addr[16];
232 TQ_UINT32 sin6_scope_id;
236 #define MIN_SOCKADDR_LEN sizeof(TQ_UINT16)
237 #define SOCKADDR_IN_LEN sizeof(sockaddr_in)
238 #define MIN_SOCKADDR_IN6_LEN ((unsigned long) &(((our_sockaddr_in6*)0)->sin6_scope_id))
239 #define SOCKADDR_IN6_LEN sizeof(our_sockaddr_in6)
240 #define MIN_SOCKADDR_UN_LEN (sizeof(TQ_UINT16) + sizeof(char))
243 class KNetwork::TDESocketAddressData
254 QMixSocketAddressRef(TDESocketAddressData* d)
259 QMixSocketAddressRef ref;
263 struct sockaddr *
generic;
264 struct sockaddr_in *in;
265 struct our_sockaddr_in6 *in6;
266 struct sockaddr_un *un;
268 TQ_UINT16 curlen, reallen;
270 TDESocketAddressData()
278 ~TDESocketAddressData()
280 if (addr.generic != 0L)
284 inline bool invalid()
const
285 {
return reallen == 0; }
287 inline void invalidate()
290 void dup(
const sockaddr* sa, TQ_UINT16 len,
bool clear =
true);
296 switch (addr.generic->sa_family)
305 oldport = addr.in6->sin6_port;
312 dup(0L, SOCKADDR_IN_LEN);
314 addr.in->sin_family = AF_INET;
315 #ifdef HAVE_STRUCT_SOCKADDR_SA_LEN
316 addr.in->sin_len = SOCKADDR_IN_LEN;
318 addr.in->sin_port = oldport;
325 switch (addr.generic->sa_family)
329 oldport = addr.in->sin_port;
342 dup(0L, SOCKADDR_IN6_LEN);
344 addr.in6->sin6_family = AF_INET6;
346 #ifdef HAVE_STRUCT_SOCKADDR_SA_LEN
347 addr.in6->sin6_len = SOCKADDR_IN6_LEN;
349 addr.in6->sin6_port = oldport;
356 void TDESocketAddressData::dup(
const sockaddr* sa, TQ_UINT16 len,
bool clear)
358 if (len < MIN_SOCKADDR_LEN)
365 if (sa && ((sa->sa_family == AF_INET && len < SOCKADDR_IN_LEN) ||
367 (sa->sa_family == AF_INET6 && len < MIN_SOCKADDR_IN6_LEN) ||
369 (sa->sa_family == AF_UNIX && len < MIN_SOCKADDR_UN_LEN)))
384 addr.generic = (sockaddr*)realloc(addr.generic, curlen);
389 memcpy(addr.generic, sa, len);
392 if (addr.generic->sa_family == AF_INET)
393 reallen = SOCKADDR_IN_LEN;
395 else if (addr.generic->sa_family == AF_INET6)
401 if (reallen < SOCKADDR_IN6_LEN)
402 addr.in6->sin6_scope_id = 0;
404 reallen = SOCKADDR_IN6_LEN;
407 else if (addr.generic->sa_family == AF_UNIX)
408 reallen = MIN_SOCKADDR_UN_LEN + strlen(addr.un->sun_path);
412 memset(addr.generic, 0, len);
413 addr.generic->sa_family = AF_UNSPEC;
419 : d(new TDESocketAddressData)
425 : d(new TDESocketAddressData)
431 : d(new(TDESocketAddressData))
446 d->ref.KInetSocketAddress::d = 0L;
447 d->ref.KUnixSocketAddress::d = 0L;
454 if (other.d && !other.d->invalid())
455 d->dup(other.d->addr.generic, other.d->reallen);
465 return d->addr.generic;
472 return d->addr.generic;
477 if (sa != 0L && len >= MIN_SOCKADDR_LEN)
494 d->dup((sockaddr*)0L, len,
false);
503 return d->addr.generic->sa_family;
509 d->dup((sockaddr*)0L, MIN_SOCKADDR_LEN);
510 d->addr.generic->sa_family =
family;
519 return other.d->invalid();
522 if (d->addr.generic->sa_family != other.d->addr.generic->sa_family)
527 switch (d->addr.generic->sa_family)
531 Q_ASSERT(d->reallen == SOCKADDR_IN_LEN);
532 Q_ASSERT(other.d->reallen == SOCKADDR_IN_LEN);
533 return memcmp(d->addr.in, other.d->addr.in, SOCKADDR_IN_LEN) == 0;
539 Q_ASSERT(d->reallen >= MIN_SOCKADDR_IN6_LEN);
540 Q_ASSERT(other.d->reallen >= MIN_SOCKADDR_IN6_LEN);
542 # if !defined(HAVE_STRUCT_SOCKADDR_IN6) || defined(HAVE_STRUCT_SOCKADDR_IN6_SIN6_SCOPE_ID)
544 if (d->reallen != other.d->reallen)
546 if (memcmp(d->addr.in6, other.d->addr.in6, MIN_SOCKADDR_IN6_LEN) != 0)
548 if (d->reallen > other.d->reallen)
549 return d->addr.in6->sin6_scope_id == 0;
551 return other.d->addr.in6->sin6_scope_id == 0;
555 return memcmp(d->addr.in6, other.d->addr.in6, d->reallen) == 0;
560 Q_ASSERT(d->reallen >= MIN_SOCKADDR_UN_LEN);
561 Q_ASSERT(other.d->reallen >= MIN_SOCKADDR_UN_LEN);
564 return strcmp(d->addr.un->sun_path, other.d->addr.un->sun_path) == 0;
569 if (d->reallen == other.d->reallen)
570 return memcmp(d->addr.generic, other.d->addr.generic, d->reallen) == 0;
579 return TQString::null;
581 switch (d->addr.generic->sa_family)
588 TQString scopeid(
"%");
589 if (d->addr.generic->sa_family == AF_INET6 && d->addr.in6->sin6_scope_id)
590 scopeid += TQString::number(d->addr.in6->sin6_scope_id);
593 return d->ref.ipAddress().toString() + scopeid;
595 return d->ref.ipAddress().toString();
600 return TQString::null;
606 return TQString::null;
608 switch (d->addr.generic->sa_family)
614 return TQString::number(d->ref.port());
617 return d->ref.pathname();
620 return TQString::null;
626 return TQString::null;
630 if (d->addr.generic->sa_family == AF_INET)
633 else if (d->addr.generic->sa_family == AF_INET6)
636 else if (d->addr.generic->sa_family == AF_UNIX)
637 return TQString::fromLatin1(
"unix:%1").arg(
serviceName());
639 return i18n(
"1: the unknown socket address family number",
640 "Unknown family %1").arg(d->addr.generic->sa_family);
766 switch (d->addr.generic->sa_family)
789 switch (d->addr.generic->sa_family)
798 return KIpAddress(&d->addr.in6->sin6_addr, 6);
812 memcpy(&d->addr.in->sin_addr, ip.
addr(),
sizeof(d->addr.in->sin_addr));
817 memcpy(&d->addr.in6->sin6_addr, ip.
addr(),
sizeof(d->addr.in6->sin6_addr));
834 switch (d->addr.generic->sa_family)
838 return ntohs(d->addr.in->sin_port);
844 return ntohs(d->addr.in6->sin6_port);
857 switch (d->addr.generic->sa_family)
861 d->addr.in->sin_port = htons(port);
868 d->addr.in6->sin6_port = htons(port);
898 if (!d->invalid() && d->addr.in6->sin6_family == AF_INET6)
899 return d->addr.in6->sin6_flowinfo;
907 d->addr.in6->sin6_flowinfo =
flowinfo;
917 if (!d->invalid() && d->addr.in6->sin6_family == AF_INET6)
918 return d->addr.in6->sin6_scope_id;
926 d->addr.in6->sin6_scope_id = scopeid;
930 void KInetSocketAddress::update()
932 if (d->addr.generic->sa_family == AF_INET)
935 else if (d->addr.generic->sa_family == AF_INET6)
949 if (!d->invalid() && d->addr.un->sun_family != AF_UNIX)
980 if (!d->invalid() && d->addr.un->sun_family == AF_UNIX)
981 return TQFile::decodeName(d->addr.un->sun_path);
982 return TQString::null;
987 d->dup(0L, MIN_SOCKADDR_UN_LEN + path.length());
988 d->addr.un->sun_family = AF_UNIX;
989 strcpy(d->addr.un->sun_path, TQFile::encodeName(path));
991 #ifdef HAVE_STRUCT_SOCKADDR_SA_LEN
992 d->addr.un->sun_len = d->reallen;