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);
201 inet_ntop(AF_INET6, m_data, buf,
sizeof(buf) - 1);
203 return TQString::fromLatin1(buf);
206 return TQString::null;
219 struct our_sockaddr_in6
221 # ifdef HAVE_STRUCT_SOCKADDR_SA_LEN
223 TQ_UINT8 sin6_family;
225 TQ_UINT16 sin6_family;
228 TQ_UINT32 sin6_flowinfo;
229 TQ_UINT8 sin6_addr[16];
230 TQ_UINT32 sin6_scope_id;
234 #define MIN_SOCKADDR_LEN sizeof(TQ_UINT16)
235 #define SOCKADDR_IN_LEN sizeof(sockaddr_in)
236 #define MIN_SOCKADDR_IN6_LEN ((unsigned long) &(((our_sockaddr_in6*)0)->sin6_scope_id))
237 #define SOCKADDR_IN6_LEN sizeof(our_sockaddr_in6)
238 #define MIN_SOCKADDR_UN_LEN (sizeof(TQ_UINT16) + sizeof(char))
241 class KNetwork::TDESocketAddressData
252 QMixSocketAddressRef(TDESocketAddressData* d)
257 QMixSocketAddressRef ref;
261 struct sockaddr *
generic;
262 struct sockaddr_in *in;
263 struct our_sockaddr_in6 *in6;
264 struct sockaddr_un *un;
266 TQ_UINT16 curlen, reallen;
268 TDESocketAddressData()
276 ~TDESocketAddressData()
278 if (addr.generic != 0L)
282 inline bool invalid()
const
283 {
return reallen == 0; }
285 inline void invalidate()
288 void dup(
const sockaddr* sa, TQ_UINT16 len,
bool clear =
true);
294 switch (addr.generic->sa_family)
300 oldport = addr.in6->sin6_port;
306 dup(0L, SOCKADDR_IN_LEN);
308 addr.in->sin_family = AF_INET;
309 #ifdef HAVE_STRUCT_SOCKADDR_SA_LEN
310 addr.in->sin_len = SOCKADDR_IN_LEN;
312 addr.in->sin_port = oldport;
319 switch (addr.generic->sa_family)
322 oldport = addr.in->sin_port;
332 dup(0L, SOCKADDR_IN6_LEN);
334 addr.in6->sin6_family = AF_INET6;
336 #ifdef HAVE_STRUCT_SOCKADDR_SA_LEN
337 addr.in6->sin6_len = SOCKADDR_IN6_LEN;
339 addr.in6->sin6_port = oldport;
346 void TDESocketAddressData::dup(
const sockaddr* sa, TQ_UINT16 len,
bool clear)
348 if (len < MIN_SOCKADDR_LEN)
355 if (sa && ((sa->sa_family == AF_INET && len < SOCKADDR_IN_LEN) ||
357 (sa->sa_family == AF_INET6 && len < MIN_SOCKADDR_IN6_LEN) ||
359 (sa->sa_family == AF_UNIX && len < MIN_SOCKADDR_UN_LEN)))
374 addr.generic = (sockaddr*)realloc(addr.generic, curlen);
379 memcpy(addr.generic, sa, len);
382 if (addr.generic->sa_family == AF_INET)
383 reallen = SOCKADDR_IN_LEN;
385 else if (addr.generic->sa_family == AF_INET6)
391 if (reallen < SOCKADDR_IN6_LEN)
392 addr.in6->sin6_scope_id = 0;
394 reallen = SOCKADDR_IN6_LEN;
397 else if (addr.generic->sa_family == AF_UNIX)
398 reallen = MIN_SOCKADDR_UN_LEN + strlen(addr.un->sun_path);
402 memset(addr.generic, 0, len);
403 addr.generic->sa_family = AF_UNSPEC;
409 : d(new TDESocketAddressData)
415 : d(new TDESocketAddressData)
421 : d(new(TDESocketAddressData))
436 d->ref.KInetSocketAddress::d = 0L;
437 d->ref.KUnixSocketAddress::d = 0L;
444 if (other.d && !other.d->invalid())
445 d->dup(other.d->addr.generic, other.d->reallen);
455 return d->addr.generic;
462 return d->addr.generic;
467 if (sa != 0L && len >= MIN_SOCKADDR_LEN)
484 d->dup((sockaddr*)0L, len,
false);
493 return d->addr.generic->sa_family;
499 d->dup((sockaddr*)0L, MIN_SOCKADDR_LEN);
500 d->addr.generic->sa_family =
family;
509 return other.d->invalid();
512 if (d->addr.generic->sa_family != other.d->addr.generic->sa_family)
517 switch (d->addr.generic->sa_family)
520 Q_ASSERT(d->reallen == SOCKADDR_IN_LEN);
521 Q_ASSERT(other.d->reallen == SOCKADDR_IN_LEN);
522 return memcmp(d->addr.in, other.d->addr.in, SOCKADDR_IN_LEN) == 0;
526 Q_ASSERT(d->reallen >= MIN_SOCKADDR_IN6_LEN);
527 Q_ASSERT(other.d->reallen >= MIN_SOCKADDR_IN6_LEN);
529 # if !defined(HAVE_STRUCT_SOCKADDR_IN6) || defined(HAVE_STRUCT_SOCKADDR_IN6_SIN6_SCOPE_ID)
531 if (d->reallen != other.d->reallen)
533 if (memcmp(d->addr.in6, other.d->addr.in6, MIN_SOCKADDR_IN6_LEN) != 0)
535 if (d->reallen > other.d->reallen)
536 return d->addr.in6->sin6_scope_id == 0;
538 return other.d->addr.in6->sin6_scope_id == 0;
542 return memcmp(d->addr.in6, other.d->addr.in6, d->reallen) == 0;
546 Q_ASSERT(d->reallen >= MIN_SOCKADDR_UN_LEN);
547 Q_ASSERT(other.d->reallen >= MIN_SOCKADDR_UN_LEN);
550 return strcmp(d->addr.un->sun_path, other.d->addr.un->sun_path) == 0;
555 if (d->reallen == other.d->reallen)
556 return memcmp(d->addr.generic, other.d->addr.generic, d->reallen) == 0;
565 return TQString::null;
567 switch (d->addr.generic->sa_family)
573 TQString scopeid(
"%");
574 if (d->addr.generic->sa_family == AF_INET6 && d->addr.in6->sin6_scope_id)
575 scopeid += TQString::number(d->addr.in6->sin6_scope_id);
578 return d->ref.ipAddress().toString() + scopeid;
580 return d->ref.ipAddress().toString();
585 return TQString::null;
591 return TQString::null;
593 switch (d->addr.generic->sa_family)
599 return TQString::number(d->ref.port());
602 return d->ref.pathname();
605 return TQString::null;
611 return TQString::null;
615 if (d->addr.generic->sa_family == AF_INET)
618 else if (d->addr.generic->sa_family == AF_INET6)
621 else if (d->addr.generic->sa_family == AF_UNIX)
622 return TQString::fromLatin1(
"unix:%1").arg(
serviceName());
624 return i18n(
"1: the unknown socket address family number",
625 "Unknown family %1").arg(d->addr.generic->sa_family);
743 switch (d->addr.generic->sa_family)
762 switch (d->addr.generic->sa_family)
768 return KIpAddress(&d->addr.in6->sin6_addr, 6);
781 memcpy(&d->addr.in->sin_addr, ip.
addr(),
sizeof(d->addr.in->sin_addr));
786 memcpy(&d->addr.in6->sin6_addr, ip.
addr(),
sizeof(d->addr.in6->sin6_addr));
803 switch (d->addr.generic->sa_family)
806 return ntohs(d->addr.in->sin_port);
810 return ntohs(d->addr.in6->sin6_port);
822 switch (d->addr.generic->sa_family)
825 d->addr.in->sin_port = htons(port);
830 d->addr.in6->sin6_port = htons(port);
859 if (!d->invalid() && d->addr.in6->sin6_family == AF_INET6)
860 return d->addr.in6->sin6_flowinfo;
868 d->addr.in6->sin6_flowinfo =
flowinfo;
878 if (!d->invalid() && d->addr.in6->sin6_family == AF_INET6)
879 return d->addr.in6->sin6_scope_id;
887 d->addr.in6->sin6_scope_id = scopeid;
891 void KInetSocketAddress::update()
893 if (d->addr.generic->sa_family == AF_INET)
896 else if (d->addr.generic->sa_family == AF_INET6)
910 if (!d->invalid() && d->addr.un->sun_family != AF_UNIX)
941 if (!d->invalid() && d->addr.un->sun_family == AF_UNIX)
942 return TQFile::decodeName(d->addr.un->sun_path);
943 return TQString::null;
948 d->dup(0L, MIN_SOCKADDR_UN_LEN + path.length());
949 d->addr.un->sun_family = AF_UNIX;
950 strcpy(d->addr.un->sun_path, TQFile::encodeName(path));
952 #ifdef HAVE_STRUCT_SOCKADDR_SA_LEN
953 d->addr.un->sun_len = d->reallen;