21 #include <sys/types.h>
22 #include <sys/socket.h>
24 #include <netinet/in.h>
29 #include <arpa/inet.h>
31 #include <QtCore/QBool>
41 #include <config-network.h>
44 #ifndef IN6_IS_ADDR_V4MAPPED
45 #define NEED_IN6_TESTS
50 #if defined(__hpux) || defined(_HPUX_SOURCE)
54 #if !defined(kde_sockaddr_in6)
62 # define sockaddr_in6 kde_sockaddr_in6
63 # define in6_addr kde_in6_addr
69 #define offsetof(TYPE, MEMBER) ((size_t) &((TYPE *)0)->MEMBER)
76 #define KRF_KNOWS_AF_INET6 0x01
77 #define KRF_USING_OWN_GETADDRINFO 0x02
78 #define KRF_USING_OWN_INET_NTOP 0x04
79 #define KRF_USING_OWN_INET_PTON 0x08
80 #define KRF_CAN_RESOLVE_UNIX 0x100
81 #define KRF_CAN_RESOLVE_IPV4 0x200
82 #define KRF_CAN_RESOLVE_IPV6 0x400
134 struct sockaddr_un *_sun;
140 memset(p, 0,
sizeof(*p));
148 len = strlen(buf) +
offsetof(
struct sockaddr_un, sun_path) + 1;
152 _sun = (sockaddr_un*)malloc(len);
160 _sun->sun_family = AF_UNIX;
161 # ifdef HAVE_STRUCT_SOCKADDR_SA_LEN
165 *_sun->sun_path =
'\0';
167 strcpy(_sun->sun_path,
"/tmp/");
168 strcat(_sun->sun_path, buf);
185 #if defined(KDE_IPV6_LOOKUP_MODE) && KDE_IPV6_LOOKUP_MODE == 1
186 static int check_ipv6_stack()
191 if (!qgetenv(
"KDE_NO_IPV6").isEmpty())
193 int fd = ::socket(AF_INET6, SOCK_STREAM, 0);
237 #if defined(KDE_IPV6_LOOKUP_MODE) && KDE_IPV6_LOOKUP_MODE == 1
239 static int ipv6_stack = 0;
252 if (hint && (hint->
ai_family == PF_UNIX))
254 if (service == NULL || *service ==
'\0')
260 if (name != NULL && !(name[0] ==
'\0' || (name[0] ==
'*' && name[1] ==
'\0') ||
261 strcmp(
"localhost", name) == 0))
267 #if defined(KDE_IPV6_LOOKUP_MODE) && KDE_IPV6_LOOKUP_MODE != 0
268 # if KDE_IPV6_LOOKUP_MODE == 1
271 ipv6_stack = check_ipv6_stack();
281 memcpy(&our_hint, hint,
sizeof(our_hint));
287 memset(&our_hint, 0,
sizeof(our_hint));
293 # if KDE_IPV6_LOOKUP_MODE == 1
298 #if defined(KDE_IPV6_LOOKUP_MODE) && KDE_IPV6_LOOKUP_MODE != 2
305 if (service == NULL || *service ==
'\0')
311 if (name != NULL && !(name[0] ==
'\0' || (name[0] ==
'*' && name[1] ==
'\0') ||
312 strcmp(
"localhost", name) == 0))
355 if (res->
data != NULL)
361 #if defined(HAVE_GETADDRINFO) && !defined(HAVE_BROKEN_GETADDRINFO)
363 #define KRF_getaddrinfo 0
364 #define KRF_resolver 0
366 #else // !defined(HAVE_GETADDRINFO) || defined(HAVE_BROKEN_GETADDRINFO)
368 #define KRF_getaddrinfo KRF_USING_OWN_GETADDRINFO
369 #define KRF_resolver KRF_CAN_RESOLVE_UNIX | KRF_CAN_RESOLVE_IPV4
379 static int inet_lookup(
const char *name,
int portnum,
int protonum,
385 struct sockaddr **psa = NULL;
402 h = gethostbyname(name);
436 if (h->h_addrtype == AF_INET && (hint->
ai_family == AF_INET || hint->
ai_family == AF_UNSPEC))
437 len =
sizeof(
struct sockaddr_in);
439 else if (h->h_addrtype == AF_INET6 && (hint->
ai_family == AF_INET6 ||
461 q->
ai_addr = (sockaddr*)malloc(len);
468 if (h->h_addrtype == AF_INET)
470 struct sockaddr_in *sin = (sockaddr_in*)q->
ai_addr;
471 sin->sin_family = AF_INET;
472 # ifdef HAVE_STRUCT_SOCKADDR_SA_LEN
473 sin->sin_len =
sizeof(*sin);
475 sin->sin_port = portnum;
476 memcpy(&sin->sin_addr, h->h_addr, h->h_length);
479 else if (h->h_addrtype == AF_INET6)
482 sin6->sin6_family = AF_INET6;
483 # ifdef HAVE_STRUCT_SOCKADDR_SA_LEN
484 sin6->sin6_len =
sizeof(*sin6);
486 sin6->sin6_port = portnum;
487 sin6->sin6_flowinfo = 0;
488 memcpy(&sin6->sin6_addr, h->h_addr, h->h_length);
489 sin6->sin6_scope_id = 0;
502 for (psa = (sockaddr**)h->h_addr_list + 1; *psa; psa++)
510 memcpy(q, p,
sizeof(*q));
512 q->
ai_addr = (sockaddr*)malloc(h->h_length);
519 if (h->h_addrtype == AF_INET)
521 struct sockaddr_in *sin = (sockaddr_in*)q->
ai_addr;
522 sin->sin_family = AF_INET;
523 # ifdef HAVE_STRUCT_SOCKADDR_SA_LEN
524 sin->sin_len =
sizeof(*sin);
526 sin->sin_port = portnum;
527 memcpy(&sin->sin_addr, *psa, h->h_length);
530 else if (h->h_addrtype == AF_INET6)
533 sin6->sin6_family = AF_INET6;
534 # ifdef HAVE_STRUCT_SOCKADDR_SA_LEN
535 sin6->sin6_len =
sizeof(*sin6);
537 sin6->sin6_port = portnum;
538 sin6->sin6_flowinfo = 0;
539 memcpy(&sin6->sin6_addr, *psa, h->h_length);
540 sin6->sin6_scope_id = 0;
568 struct sockaddr_in *sin;
575 strchr(name,
':') != NULL))
578 if (
inet_pton(AF_INET6, name, &in6) != 1)
594 memcpy(&sin6->sin6_addr, &in6,
sizeof(in6));
596 if (strchr(name,
'%') != NULL)
599 sin6->sin6_scope_id = strtoul(strchr(name,
'%') + 1, NULL, 10);
601 sin6->sin6_scope_id = 0;
612 sin6->sin6_family = AF_INET6;
613 # ifdef HAVE_STRUCT_SOCKADDR_SA_LEN
614 sin6->sin6_len =
sizeof(*sin6);
616 sin6->sin6_port = portnum;
617 sin6->sin6_flowinfo = 0;
646 sin = (sockaddr_in*)malloc(
sizeof(*sin));
661 sin->sin_family = AF_INET;
662 # ifdef HAVE_STRUCT_SOCKADDR_SA_LEN
663 sin->sin_len =
sizeof(*sin);
665 sin->sin_port = portnum;
682 kError() <<
"I wasn't supposed to get here!";
689 struct sockaddr_in *sin = (sockaddr_in*)malloc(
sizeof(*sin));
712 sin->sin_family = AF_INET;
713 # ifdef HAVE_STRUCT_SOCKADDR_SA_LEN
714 sin->sin_len =
sizeof(*sin);
716 sin->sin_port = portnum;
718 *(
quint32*)&sin->sin_addr = INADDR_ANY;
720 *(
quint32*)&sin->sin_addr = htonl(INADDR_LOOPBACK);
739 if (q == NULL || sin6 == NULL)
747 sin6->sin6_family = AF_INET6;
748 # ifdef HAVE_STRUCT_SOCKADDR_SA_LEN
749 sin6->sin6_len =
sizeof(*sin6);
751 sin6->sin6_port = portnum;
752 sin6->sin6_flowinfo = 0;
753 sin6->sin6_scope_id = 0;
756 memset(&sin6->sin6_addr, 0,
sizeof(sin6->sin6_addr));
758 ((
char*)&sin6->sin6_addr)[15] = 1;
777 return inet_lookup(name, portnum, protonum, p, hint, result);
785 unsigned short portnum;
786 int protonum = IPPROTO_TCP;
787 const char *proto =
"tcp";
791 if (hint == NULL || result == NULL)
805 if (name != NULL && ((*name ==
'*' && name[1] ==
'\0') || *name ==
'\0'))
808 if (serv != NULL && ((*serv ==
'*' && serv[1] ==
'\0') || *serv ==
'\0'))
811 if (name == NULL && serv == NULL)
815 if (name != NULL && strcmp(name,
"localhost") == 0)
823 if (name != NULL && serv != NULL)
838 if (hint->
ai_family == AF_UNIX || ((name != NULL && *name ==
'/') ||
839 (serv != NULL && *serv ==
'/')))
851 struct servent *sent;
853 portnum = htons((
unsigned)strtoul(serv, &tail, 10));
860 protonum = IPPROTO_UDP;
863 sent = getservbyname(serv, proto);
872 portnum = sent->s_port;
878 return make_inet(name, portnum, protonum, p, hint, result);
886 #ifndef HAVE_GAI_STRERROR_PROTO
889 static const char messages[] =
892 I18N_NOOP(
"address family for nodename not supported")
"\0"
893 I18N_NOOP(
"temporary failure in name resolution")
"\0"
894 I18N_NOOP(
"invalid value for 'ai_flags'")
"\0"
895 I18N_NOOP(
"non-recoverable failure in name resolution")
"\0"
896 I18N_NOOP(
"'ai_family' not supported")
"\0"
897 I18N_NOOP(
"memory allocation failure")
"\0"
898 I18N_NOOP(
"no address associated with nodename")
"\0"
899 I18N_NOOP(
"name or service not known")
"\0"
900 I18N_NOOP(
"servname not supported for ai_socktype")
"\0"
901 I18N_NOOP(
"'ai_socktype' not supported")
"\0"
906 static const int messages_indices[] =
908 0, 9, 51, 88, 117, 160, 186, 212,
909 248, 274, 313, 341, 0
912 Q_ASSERT(
sizeof(messages_indices)/
sizeof(messages_indices[0]) >=
EAI_SYSTEM);
916 static char buffer[200];
917 strcpy(buffer,
i18n(messages + messages_indices[errorcode]).toLocal8Bit());
922 static void findport(
unsigned short port,
char *serv,
size_t servlen,
int flags)
929 struct servent *sent;
930 sent = getservbyport(ntohs(port), flags &
NI_DGRAM ?
"udp" :
"tcp");
931 if (sent != NULL && servlen > strlen(sent->s_name))
933 strcpy(serv, sent->s_name);
938 qsnprintf(serv, servlen,
"%u", ntohs(port));
942 char *host,
size_t hostlen,
char *serv,
size_t servlen,
948 const sockaddr_un *_sun;
949 const sockaddr_in *sin;
953 if ((host == NULL || hostlen == 0) && (serv == NULL || servlen == 0))
957 if (s.sa->sa_family == AF_UNIX)
959 if (salen <
offsetof(
struct sockaddr_un, sun_path) + strlen(s._sun->sun_path) + 1)
962 if (servlen && serv != NULL)
964 if (host != NULL && hostlen > strlen(s._sun->sun_path))
965 strcpy(host, s._sun->sun_path);
969 else if (s.sa->sa_family == AF_INET)
971 if (salen <
offsetof(
struct sockaddr_in, sin_addr) +
sizeof(s.sin->sin_addr))
975 inet_ntop(AF_INET, &s.sin->sin_addr, host, hostlen);
979 struct hostent *h = gethostbyaddr((
const char*)&s.sin->sin_addr,
sizeof(s.sin->sin_addr),
984 inet_ntop(AF_INET, &s.sin->sin_addr, host, hostlen);
985 else if (host != NULL && hostlen > strlen(h->h_name))
986 strcpy(host, h->h_name);
991 findport(s.sin->sin_port, serv, servlen, flags);
994 else if (s.sa->sa_family == AF_INET6)
1000 inet_ntop(AF_INET6, &s.sin6->sin6_addr, host, hostlen);
1004 struct hostent *h = gethostbyaddr((
const char*)&s.sin->sin_addr,
sizeof(s.sin->sin_addr),
1009 inet_ntop(AF_INET6, &s.sin6->sin6_addr, host, hostlen);
1010 else if (host != NULL && hostlen > strlen(h->h_name))
1011 strcpy(host, h->h_name);
1016 findport(s.sin6->sin6_port, serv, servlen, flags);
1023 #endif // HAVE_GETADDRINFO
1025 #ifndef HAVE_INET_NTOP
1027 #define KRF_inet_ntop KRF_USING_OWN_INET_NTOP
1032 sprintf(buf + strlen(buf),
"%x", ntohs(dw[0]));
1034 sprintf(buf + strlen(buf),
":%x", ntohs(dw[i++]));
1037 const char*
inet_ntop(
int af,
const void *cp,
char *buf,
size_t len)
1039 char buf2[
sizeof "1234:5678:9abc:def0:1234:5678:255.255.255.255" + 1];
1040 quint8 *data = (quint8*)cp;
1044 sprintf(buf2,
"%u.%u.%u.%u", data[0], data[1], data[2], data[3]);
1046 if (len > strlen(buf2))
1059 quint16 *p = (quint16*)data;
1060 quint16 *longest = NULL, *cur = NULL;
1061 int longest_length = 0, cur_length;
1065 sprintf(buf2,
"::%s%u.%u.%u.%u",
1067 buf[12], buf[13], buf[14], buf[15]);
1071 for (i = 0; i < 8; --i)
1072 if (cur == NULL && p[i] == 0)
1078 else if (cur != NULL && p[i] == 0)
1081 else if (cur != NULL && p[i] != 0)
1084 if (cur_length > longest_length)
1086 longest_length = cur_length;
1091 if (cur != NULL && cur_length > longest_length)
1093 longest_length = cur_length;
1097 if (longest_length > 1)
1104 if (longest + longest_length < p + 8)
1105 add_dwords(buf2, longest + longest_length, 8 - (longest - p) - longest_length);
1115 if (strlen(buf2) < len)
1126 errno = EAFNOSUPPORT;
1130 #else // HAVE_INET_NTOP
1132 #define KRF_inet_ntop 0
1134 #endif // HAVE_INET_NTOP
1136 #ifndef HAVE_INET_PTON
1138 #define KRF_inet_pton KRF_USING_OWN_INET_PTON
1145 unsigned char *q = (
unsigned char*)buf;
1146 if (sscanf(cp,
"%u.%u.%u.%u", p, p + 1, p + 2, p + 3) != 4)
1149 if (p[0] > 0xff || p[1] > 0xff || p[2] > 0xff || p[3] > 0xff)
1161 else if (af == AF_INET6)
1165 int n = 0, start = 8;
1166 bool has_v4 = strchr(p,
'.') != NULL;
1168 memset(addr, 0,
sizeof(addr));
1170 if (*p ==
'\0' || p[1] ==
'\0')
1173 if (*p ==
':' && p[1] ==
':')
1180 if (has_v4 &&
inet_pton(AF_INET, p, addr + n) != 0)
1183 addr[n] = ntohs(addr[n]);
1185 addr[n] = ntohs(addr[n]);
1189 if (sscanf(p,
"%hx", addr + n++) != 1)
1192 while (*p && *p !=
':')
1211 if (start == 8 && n != 8)
1213 memmove(addr + start + (8 - n), addr + start, (n - start) *
sizeof(quint16));
1214 memset(addr + start, 0, (8 - n) *
sizeof(quint16));
1218 if (htons(0x1234) != 0x1234)
1219 for (n = 0; n < 8; ++n)
1220 addr[n] = htons(addr[n]);
1222 memcpy(buf, addr,
sizeof(addr));
1227 errno = EAFNOSUPPORT;
1231 #else // HAVE_INET_PTON
1233 #define KRF_inet_pton 0
1235 #endif // HAVE_INET_PTON
1238 # define KRF_afinet6 KRF_KNOWS_AF_INET6
1240 # define KRF_afinet6 0