1 /* net.cc: network-related routines.
3 This file is part of Cygwin.
5 This software is a copyrighted work licensed under the terms of the
6 Cygwin license. Please consult the file "CYGWIN_LICENSE" for
9 /* #define DEBUG_NEST_ON 1 */
11 #define __INSIDE_CYGWIN_NET__
12 #define USE_SYS_TYPES_FD_SET
13 #define __WSA_ERR_MACROS_DEFINED
15 /* 2014-04-24: Current Mingw headers define sockaddr_in6 using u_long (8 byte)
16 because a redefinition for LP64 systems is missing. This leads to a wrong
17 definition and size of sockaddr_in6 when building with winsock headers. */
19 #define u_long __ms_u_long
20 #include <w32api/ws2tcpip.h>
21 #include <w32api/mswsock.h>
22 #include <w32api/iphlpapi.h>
23 #define gethostname cygwin_gethostname
28 #include <asm/byteorder.h>
29 #include "shared_info.h"
36 /* Unfortunately defined in Windows header files and arpa/nameser_compat.h. */
46 int sscanf (const char *, const char *, ...);
47 int cygwin_inet_pton(int, const char *, void *);
48 const char *cygwin_inet_ntop (int, const void *, char *, socklen_t
);
49 int dn_length1(const unsigned char *, const unsigned char *,
50 const unsigned char *);
51 } /* End of "C" section */
53 const struct in6_addr in6addr_any
= IN6ADDR_ANY_INIT
;
54 const struct in6_addr in6addr_loopback
= IN6ADDR_LOOPBACK_INIT
;
56 static fhandler_socket
*
59 cygheap_fdget
cfd (fd
);
64 fhandler_socket
*const fh
= cfd
->is_socket ();
66 if (!fh
|| (fh
->get_flags () & O_PATH
))
75 /* exported as inet_ntoa: BSD 4.3 */
77 cygwin_inet_ntoa (struct in_addr in
)
80 const char *res
= cygwin_inet_ntop (AF_INET
, &in
, buf
, sizeof buf
);
82 if (_my_tls
.locals
.ntoa_buf
)
84 free (_my_tls
.locals
.ntoa_buf
);
85 _my_tls
.locals
.ntoa_buf
= NULL
;
88 _my_tls
.locals
.ntoa_buf
= strdup (res
);
89 return _my_tls
.locals
.ntoa_buf
;
92 /* inet_netof is in the standard BSD sockets library. It is useless
93 for modern networks, since it assumes network values which are no
94 longer meaningful, but some existing code calls it. */
96 extern "C" unsigned long
97 inet_netof (struct in_addr in
)
101 i
= ntohl (in
.s_addr
);
103 res
= (i
& IN_CLASSA_NET
) >> IN_CLASSA_NSHIFT
;
104 else if (IN_CLASSB (i
))
105 res
= (i
& IN_CLASSB_NET
) >> IN_CLASSB_NSHIFT
;
107 res
= (i
& IN_CLASSC_NET
) >> IN_CLASSC_NSHIFT
;
112 /* inet_makeaddr is in the standard BSD sockets library. It is
113 useless for modern networks, since it assumes network values which
114 are no longer meaningful, but some existing code calls it. */
116 extern "C" struct in_addr
117 inet_makeaddr (int net
, int lna
)
122 if (net
< IN_CLASSA_MAX
)
123 i
= (net
<< IN_CLASSA_NSHIFT
) | (lna
& IN_CLASSA_HOST
);
124 else if (net
< IN_CLASSB_MAX
)
125 i
= (net
<< IN_CLASSB_NSHIFT
) | (lna
& IN_CLASSB_HOST
);
126 else if (net
< 0x1000000)
127 i
= (net
<< IN_CLASSC_NSHIFT
) | (lna
& IN_CLASSC_HOST
);
131 in
.s_addr
= htonl (i
);
137 static const int wsock_errmap
[] =
139 0, /* WSABASEERR (10000) */
143 EINTR
, /* WSAEINTR */
148 EBADF
, /* WSAEBADF */
152 EACCES
, /* WSAEACCES */
153 EFAULT
, /* WSAEFAULT */
161 EINVAL
, /* WSAEINVAL */
163 EMFILE
, /* WSAEMFILE */
174 EWOULDBLOCK
, /* WSAEWOULDBLOCK */
175 EINPROGRESS
, /* WSAEINPROGRESS */
176 EALREADY
, /* WSAEALREADY */
177 ENOTSOCK
, /* WSAENOTSOCK */
178 EDESTADDRREQ
, /* WSAEDESTADDRREQ */
179 EMSGSIZE
, /* WSAEMSGSIZE */
180 EPROTOTYPE
, /* WSAEPROTOTYPE */
181 ENOPROTOOPT
, /* WSAENOPROTOOPT */
182 EPROTONOSUPPORT
, /* WSAEPROTONOSUPPORT */
183 ESOCKTNOSUPPORT
, /* WSAESOCKTNOSUPPORT */
184 EOPNOTSUPP
, /* WSAEOPNOTSUPP */
185 EPFNOSUPPORT
, /* WSAEPFNOSUPPORT */
186 EAFNOSUPPORT
, /* WSAEAFNOSUPPORT */
187 EADDRINUSE
, /* WSAEADDRINUSE */
188 EADDRNOTAVAIL
, /* WSAEADDRNOTAVAIL */
189 ENETDOWN
, /* WSAENETDOWN */
190 ENETUNREACH
, /* WSAENETUNREACH */
191 ENETRESET
, /* WSAENETRESET */
192 ECONNABORTED
, /* WSAECONNABORTED */
193 ECONNRESET
, /* WSAECONNRESET */
194 ENOBUFS
, /* WSAENOBUFS */
195 EISCONN
, /* WSAEISCONN */
196 ENOTCONN
, /* WSAENOTCONN */
197 ESHUTDOWN
, /* WSAESHUTDOWN */
198 ETOOMANYREFS
, /* WSAETOOMANYREFS */
199 ETIMEDOUT
, /* WSAETIMEDOUT */
200 ECONNREFUSED
, /* WSAECONNREFUSED */
201 ELOOP
, /* WSAELOOP */
202 ENAMETOOLONG
, /* WSAENAMETOOLONG */
203 EHOSTDOWN
, /* WSAEHOSTDOWN */
204 EHOSTUNREACH
, /* WSAEHOSTUNREACH */
205 ENOTEMPTY
, /* WSAENOTEMPTY */
206 EPROCLIM
, /* WSAEPROCLIM */
207 EUSERS
, /* WSAEUSERS */
208 EDQUOT
, /* WSAEDQUOT */
209 ESTALE
, /* WSAESTALE */
210 EREMOTE
, /* WSAEREMOTE */
214 find_winsock_errno (DWORD why
)
218 if (why
< WSABASEERR
)
219 geterrno_from_win_error (why
, EACCES
);
222 if (why
< sizeof wsock_errmap
/ sizeof wsock_errmap
[0])
223 return wsock_errmap
[why
];
229 __set_winsock_errno (const char *fn
, int ln
)
231 DWORD werr
= WSAGetLastError ();
232 int err
= find_winsock_errno (werr
);
235 syscall_printf ("%s:%d - winsock error %u -> errno %d", fn
, ln
, werr
, err
);
238 static const struct host_errmap_t
240 DWORD w
; /* windows version of error */
241 const char *s
; /* error text returned by herror and hstrerror */
242 int e
; /* errno version of error */
244 {WSAHOST_NOT_FOUND
, "Unknown host", HOST_NOT_FOUND
},
245 {WSATRY_AGAIN
, "Host name lookup failure", TRY_AGAIN
},
246 {WSANO_RECOVERY
, "Unknown server error", NO_RECOVERY
},
247 {WSANO_DATA
, "No address associated with name", NO_DATA
},
256 DWORD why
= WSAGetLastError ();
258 for (i
= 0; host_errmap
[i
].w
!= 0; ++i
)
259 if (why
== host_errmap
[i
].w
)
262 if (host_errmap
[i
].w
!= 0)
263 h_errno
= host_errmap
[i
].e
;
265 h_errno
= NETDB_INTERNAL
;
271 return sizeof (DWORD
) * (((n
+ sizeof (DWORD
) - 1)) / sizeof (DWORD
));
275 strlen_round (const char *s
)
279 return DWORD_round (strlen (s
) + 1);
292 static const char *entnames
[] = {"host", "proto", "serv"};
295 realloc_ent (unionent
*&dst
, int sz
)
297 /* Allocate the storage needed. Allocate a rounded size to attempt to force
298 reuse of this buffer so that a poorly-written caller will not be using
300 unsigned rsz
= 256 * ((sz
+ 255) / 256);
302 if ((ptr
= (unionent
*) realloc (dst
, rsz
)))
307 static inline hostent
*
308 realloc_ent (int sz
, hostent
*)
310 return (hostent
*) realloc_ent (_my_tls
.locals
.hostent_buf
, sz
);
313 /* Generic "dup a {host,proto,serv}ent structure" function.
314 This is complicated because we need to be able to free the
315 structure at any point and we can't rely on the pointer contents
316 being untouched by callers. So, we allocate a chunk of memory
317 large enough to hold the structure and all of the stuff it points
318 to then we copy the source into this new block of memory.
319 The 'unionent' struct is a union of all of the currently used
322 /* For some baffling reason, somebody at Microsoft decided that it would be
323 a good idea to exchange the s_port and s_proto members in the servent
332 #define WIN_SERVENT(x) ((win64_servent *)(x))
339 dup_ent (unionent
*&dst
, unionent
*src
, unionent::struct_type type
)
342 debug_printf ("old %sent structure \"%s\" %p\n", entnames
[type
],
347 set_winsock_errno ();
351 debug_printf ("duping %sent \"%s\", %p", entnames
[type
], src
->name
, src
);
353 /* Find the size of the raw structure minus any character strings, etc. */
357 case unionent::t_protoent
:
358 struct_sz
= sizeof (protoent
);
360 case unionent::t_servent
:
361 struct_sz
= sizeof (servent
);
363 case unionent::t_hostent
:
364 struct_sz
= sizeof (hostent
);
367 api_fatal ("called with invalid value %d", type
);
371 /* Every *ent begins with a name. Calculate its length. */
372 int namelen
= strlen_round (src
->name
);
373 sz
= struct_sz
+ namelen
;
376 /* The next field in every *ent is an argv list of "something".
377 Calculate the number of components and how much space the
378 character strings will take. */
380 for (av
= src
->list
; av
&& *av
; av
++)
383 sz
+= sizeof (char **) + strlen_round (*av
);
386 /* NULL terminate if there actually was a list */
389 sz
+= sizeof (char **);
393 /* Do servent/hostent specific processing */
395 int addr_list_len
= 0;
396 if (type
== unionent::t_servent
)
398 if (WIN_SERVENT (src
)->s_proto
)
399 sz
+= (protolen
= strlen_round (WIN_SERVENT (src
)->s_proto
));
401 else if (type
== unionent::t_hostent
)
403 /* Calculate the length and storage used for h_addr_list */
404 for (av
= src
->h_addr_list
; av
&& *av
; av
++)
407 sz
+= sizeof (char **) + DWORD_round (src
->h_len
);
411 sz
+= sizeof (char **);
416 /* Allocate the storage needed. */
417 if (realloc_ent (dst
, sz
))
420 /* This field is common to all *ent structures but named differently
421 in each, of course. Also, take 64 bit Windows servent weirdness
423 if (type
== unionent::t_servent
)
424 dst
->port_proto_addrtype
= WIN_SERVENT (src
)->s_port
;
426 dst
->port_proto_addrtype
= src
->port_proto_addrtype
;
428 char *dp
= ((char *) dst
) + struct_sz
;
431 /* Copy the name field to dst, using space just beyond the end of
432 the dst structure. */
433 strcpy (dst
->name
= dp
, src
->name
);
437 /* Copy the 'list' type to dst, using space beyond end of structure
438 + storage for name. */
441 char **dav
= dst
->list
= (char **) dp
;
442 dp
+= sizeof (char **) * list_len
;
443 for (av
= src
->list
; av
&& *av
; av
++)
445 int len
= strlen (*av
) + 1;
446 memcpy (*dav
++ = dp
, *av
, len
);
447 dp
+= DWORD_round (len
);
451 /* Do servent/protoent/hostent specific processing. */
452 if (type
== unionent::t_protoent
)
453 debug_printf ("protoent %s %p %y", dst
->name
, dst
->list
, dst
->port_proto_addrtype
);
454 else if (type
== unionent::t_servent
)
456 if (WIN_SERVENT (src
)->s_proto
)
458 strcpy (dst
->s_proto
= dp
, WIN_SERVENT (src
)->s_proto
);
462 else if (type
== unionent::t_hostent
)
464 /* Transfer h_len and duplicate contents of h_addr_list, using
465 memory after 'list' allocation. */
466 dst
->h_len
= src
->h_len
;
467 char **dav
= dst
->h_addr_list
= (char **) dp
;
468 dp
+= sizeof (char **) * addr_list_len
;
469 for (av
= src
->h_addr_list
; av
&& *av
; av
++)
471 memcpy (*dav
++ = dp
, *av
, src
->h_len
);
472 dp
+= DWORD_round (src
->h_len
);
476 debug_printf ("duped %sent \"%s\", %p", entnames
[type
], dst
? dst
->name
: "<null!>", dst
);
480 static inline hostent
*
481 dup_ent (hostent
*src
)
483 return (hostent
*) dup_ent (_my_tls
.locals
.hostent_buf
, (unionent
*) src
, unionent::t_hostent
);
486 static inline protoent
*
487 dup_ent (protoent
*src
)
489 return (protoent
*) dup_ent (_my_tls
.locals
.protoent_buf
, (unionent
*) src
, unionent::t_protoent
);
492 static inline servent
*
493 dup_ent (servent
*src
)
495 return (servent
*) dup_ent (_my_tls
.locals
.servent_buf
, (unionent
*) src
, unionent::t_servent
);
498 /* exported as getprotobyname: POSIX.1-2001, POSIX.1-2008, 4.3BSD */
499 extern "C" struct protoent
*
500 cygwin_getprotobyname (const char *p
)
504 return dup_ent (getprotobyname (p
));
511 /* exported as getprotobynumber: POSIX.1-2001, POSIX.1-2008, 4.3BSD */
512 extern "C" struct protoent
*
513 cygwin_getprotobynumber (int number
)
515 return dup_ent (getprotobynumber (number
));
518 /* exported as socket: POSIX.1-2001, POSIX.1-2008, 4.4BSD */
520 cygwin_socket (int af
, int type
, int protocol
)
526 int flags
= type
& _SOCK_FLAG_MASK
;
527 type
&= ~_SOCK_FLAG_MASK
;
529 debug_printf ("socket (%d, %d (flags %y), %d)", af
, type
, flags
, protocol
);
534 #ifndef __WITH_AF_UNIX
538 dev
= (af
== AF_LOCAL
) ? af_local_dev
: af_unix_dev
;
539 #endif /* __WITH_AF_UNIX */
546 set_errno (EAFNOSUPPORT
);
550 if ((flags
& ~(SOCK_NONBLOCK
| SOCK_CLOEXEC
)) != 0)
561 fh
= (fhandler_socket
*) build_fh_dev (*dev
);
562 if (fh
&& fh
->socket (af
, type
, protocol
, flags
) == 0)
574 syscall_printf ("%R = socket(%d, %d (flags %y), %d)",
575 res
, af
, type
, flags
, protocol
);
579 /* exported as sendto: 4.4BSD, SVr4, POSIX.1-2001 */
581 cygwin_sendto (int fd
, const void *buf
, size_t len
, int flags
,
582 const struct sockaddr
*to
, socklen_t tolen
)
586 pthread_testcancel ();
590 fhandler_socket
*fh
= get (fd
);
592 res
= fh
->sendto (buf
, len
, flags
, to
, tolen
);
596 syscall_printf ("%lR = sendto(%d, %p, %ld, %y, %p, %d)",
597 res
, fd
, buf
, len
, flags
, to
, tolen
);
601 /* exported as recvfrom: 4.4BSD, SVr4, POSIX.1-2001 */
603 cygwin_recvfrom (int fd
, void *buf
, size_t len
, int flags
,
604 struct sockaddr
*from
, socklen_t
*fromlen
)
608 pthread_testcancel ();
612 fhandler_socket
*fh
= get (fd
);
614 /* Originally we shortcircuited here if res == 0.
615 Allow 0 bytes buffer. This is valid in POSIX and handled in
616 fhandler_socket::recv_internal. If we shortcircuit, we fail
617 to deliver valid error conditions and peer address. */
618 res
= fh
->recvfrom (buf
, len
, flags
, from
, fromlen
);
622 syscall_printf ("%lR = recvfrom(%d, %p, %ld, %y, %p, %p)",
623 res
, fd
, buf
, len
, flags
, from
, fromlen
);
627 /* exported as setsockopt: POSIX.1-2001, POSIX.1-2008, SVr4, 4.4BSD */
629 cygwin_setsockopt (int fd
, int level
, int optname
, const void *optval
,
636 fhandler_socket
*fh
= get (fd
);
638 ret
= fh
->setsockopt (level
, optname
, optval
, optlen
);
642 syscall_printf ("%R = setsockopt(%d, %d, %y, %p, %d)",
643 ret
, fd
, level
, optname
, optval
, optlen
);
647 /* exported as getsockopt: POSIX.1-2001, POSIX.1-2008, SVr4, 4.4BSD */
649 cygwin_getsockopt (int fd
, int level
, int optname
, void *optval
,
656 fhandler_socket
*fh
= get (fd
);
658 ret
= fh
->getsockopt (level
, optname
, optval
, optlen
);
662 syscall_printf ("%R = getsockopt(%d, %d, %y, %p, %p)",
663 ret
, fd
, level
, optname
, optval
, optlen
);
672 cygheap_fdget
cfd (fd
);
677 fhandler_socket
*const fh
= cfd
->is_socket ();
679 set_errno (ENOTSOCK
);
680 else if (fh
->get_flags () & O_PATH
)
682 else if (fh
->ioctl (SIOCATMARK
, &ret
) != -1)
689 getpeereid (int fd
, uid_t
*euid
, gid_t
*egid
)
691 fhandler_socket
*fh
= get (fd
);
693 return fh
->getpeereid (NULL
, euid
, egid
);
697 /* exported as connect: POSIX.1-2001, POSIX.1-2008, SVr4, 4.4BSD */
699 cygwin_connect (int fd
, const struct sockaddr
*name
, socklen_t namelen
)
703 pthread_testcancel ();
707 fhandler_socket
*fh
= get (fd
);
709 res
= fh
->connect (name
, namelen
);
713 syscall_printf ("%R = connect(%d, %p, %d)", res
, fd
, name
, namelen
);
717 /* exported as getservbyname: POSIX.1-2001, POSIX.1-2008, 4.3BSD */
718 extern "C" struct servent
*
719 cygwin_getservbyname (const char *name
, const char *proto
)
725 res
= dup_ent (getservbyname (name
, proto
));
729 syscall_printf ("%p = getservbyname (%s, %s)", res
, name
, proto
);
733 /* exported as getservbyport: POSIX.1-2001, POSIX.1-2008, 4.3BSD */
734 extern "C" struct servent
*
735 cygwin_getservbyport (int port
, const char *proto
)
741 res
= dup_ent (getservbyport (port
, proto
));
745 syscall_printf ("%p = getservbyport (%d, %s)", res
, port
, proto
);
750 cygwin_gethostname (char *name
, size_t len
)
754 PFIXED_INFO info
= NULL
;
757 if (GetNetworkParams(info
, &size
) == ERROR_BUFFER_OVERFLOW
758 && (info
= (PFIXED_INFO
) alloca(size
))
759 && GetNetworkParams(info
, &size
) == ERROR_SUCCESS
)
761 strncpy(name
, info
->HostName
, len
);
762 debug_printf ("gethostname %s", name
);
773 sethostname (const char *name
, size_t len
)
775 WCHAR wname
[MAX_COMPUTERNAME_LENGTH
+ 1];
777 sys_mbstowcs (wname
, MAX_COMPUTERNAME_LENGTH
+ 1, name
, len
);
778 if (!SetComputerNameExW (ComputerNamePhysicalDnsHostname
, wname
))
786 /* getdomainname: 4.4BSD */
788 getdomainname (char *domain
, size_t len
)
792 PFIXED_INFO info
= NULL
;
795 if (GetNetworkParams(info
, &size
) == ERROR_BUFFER_OVERFLOW
796 && (info
= (PFIXED_INFO
) alloca(size
))
797 && GetNetworkParams(info
, &size
) == ERROR_SUCCESS
)
799 strncpy(domain
, info
->DomainName
, len
);
800 debug_printf ("getdomainname %s", domain
);
810 /* exported as gethostbyname: POSIX.1-2001 */
811 extern "C" struct hostent
*
812 cygwin_gethostbyname (const char *name
)
814 unsigned char tmp_addr
[4];
815 struct hostent tmp
, *h
;
816 char *tmp_aliases
[1] = {0};
817 char *tmp_addr_list
[2] = {0,0};
818 unsigned int a
, b
, c
, d
;
824 if (sscanf (name
, "%u.%u.%u.%u%c", &a
, &b
, &c
, &d
, &dummy
) != 4
825 || a
>= 256 || b
>= 256 || c
>= 256 || d
>= 256)
826 h
= gethostbyname (name
);
829 /* In case you don't have DNS, at least x.x.x.x still works */
830 memset (&tmp
, 0, sizeof (tmp
));
835 tmp_addr_list
[0] = (char *) tmp_addr
;
837 tmp
.h_aliases
= tmp_aliases
;
840 tmp
.h_addr_list
= tmp_addr_list
;
846 debug_printf ("h_name %s", res
->h_name
);
849 debug_printf ("dup_ent returned NULL for name %s, h %p", name
, h
);
861 /* exported as gethostbyaddr: POSIX.1-2001 */
862 extern "C" struct hostent
*
863 cygwin_gethostbyaddr (const void *addr
, socklen_t len
, int type
)
869 res
= dup_ent (gethostbyaddr ((const char *) addr
, len
, type
));
871 debug_printf ("h_name %s", res
->h_name
);
884 memcpy4to6 (char *dst
, const u_int8_t
*src
)
886 const unsigned int h
[] = {0, 0, htonl (0xFFFF)};
888 memcpy (dst
+ 12, src
, NS_INADDRSZ
);
891 /* gethostby_specials: RFC 6761
892 Handles numerical addresses and special names for gethostbyname2 */
894 gethostby_specials (const char *name
, const int af
,
895 const int addrsize_in
, const int addrsize_out
)
897 int namelen
= strlen (name
);
898 /* Ignore a final '.' */
899 if ((namelen
== 0) || ((namelen
-= (name
[namelen
- 1] == '.')) == 0))
902 h_errno
= NETDB_INTERNAL
;
907 u_int8_t address
[NS_IN6ADDRSZ
];
908 /* Test for numerical addresses */
909 res
= cygwin_inet_pton(af
, name
, address
);
910 /* Test for special domain names */
914 char const match
[] = "invalid";
915 int const matchlen
= sizeof(match
) - 1;
916 int start
= namelen
- matchlen
;
917 if ((start
>= 0) && ((start
== 0) || (name
[start
-1] == '.'))
918 && (strncasecmp (&name
[start
], match
, matchlen
) == 0))
920 h_errno
= HOST_NOT_FOUND
;
925 char const match
[] = "localhost";
926 int const matchlen
= sizeof(match
) - 1;
927 int start
= namelen
- matchlen
;
928 if ((start
>= 0) && ((start
== 0) || (name
[start
-1] == '.'))
929 && (strncasecmp (&name
[start
], match
, matchlen
) == 0))
935 address
[1] = address
[2] = 0;
940 memset (address
, 0, NS_IN6ADDRSZ
);
941 address
[NS_IN6ADDRSZ
-1] = 1;
949 int const alias_count
= 0, address_count
= 1;
951 int sz
= DWORD_round (sizeof(hostent
))
952 + sizeof (char *) * (alias_count
+ address_count
+ 2)
954 + address_count
* addrsize_out
;
955 hostent
*ret
= realloc_ent (sz
, (hostent
*) NULL
);
958 /* errno is already set */
959 h_errno
= NETDB_INTERNAL
;
963 ret
->h_addrtype
= af
;
964 ret
->h_length
= addrsize_out
;
965 ret
->h_aliases
= (char **) (((char *) ret
) + DWORD_round (sizeof(hostent
)));
966 ret
->h_addr_list
= ret
->h_aliases
+ alias_count
+ 1;
967 string_ptr
= (char *) (ret
->h_addr_list
+ address_count
+ 1);
968 ret
->h_name
= string_ptr
;
970 memcpy (string_ptr
, name
, namelen
);
971 string_ptr
[namelen
] = 0;
972 string_ptr
+= namelen
+ 1;
974 ret
->h_addr_list
[0] = string_ptr
;
975 if (addrsize_in
!= addrsize_out
)
977 memcpy4to6 (string_ptr
, address
);
978 ret
->h_addrtype
= AF_INET6
;
981 memcpy (string_ptr
, address
, addrsize_out
);
983 ret
->h_aliases
[alias_count
] = NULL
;
984 ret
->h_addr_list
[address_count
] = NULL
;
990 gethostby_helper (const char *name
, const int af
, const int type
,
991 const int addrsize_in
, const int addrsize_out
)
993 /* Get the data from the name server */
994 const int maxcount
= 3;
995 int old_errno
, ancount
= 0, anlen
= 1024, msgsize
= 0;
996 unsigned char *ptr
, *msg
= NULL
;
1001 while ((anlen
> msgsize
) && (ancount
++ < maxcount
))
1004 ptr
= (unsigned char *) realloc (msg
, msgsize
);
1009 set_errno (old_errno
);
1010 h_errno
= NETDB_INTERNAL
;
1014 anlen
= res_search (name
, ns_c_in
, type
, msg
, msgsize
);
1017 if (ancount
>= maxcount
)
1020 h_errno
= NO_RECOVERY
;
1023 if (anlen
< 0) /* errno and h_errno are set */
1027 set_errno (old_errno
);
1030 unsigned char *eomsg
= msg
+ anlen
- 1;
1032 /* We scan the answer records to determine the required memory size.
1033 They can be corrupted and we don't fully trust that the message
1034 follows the standard exactly. glibc applies some checks that
1036 The answers are copied in the hostent structure in a second scan.
1037 To simplify the second scan we store information as follows:
1038 - "class" is replaced by the compressed name size
1039 - the first 16 bits of the "ttl" store the expanded name size + 1
1040 - the last 16 bits of the "ttl" store the offset to the next valid record.
1041 Note that "type" is rewritten in host byte order. */
1045 unsigned type
: 16; // type
1046 unsigned complen
: 16; // class or compressed length
1047 unsigned namelen1
: 16; // expanded length (with final 0)
1048 unsigned next_o
: 16; // offset to next valid
1049 unsigned size
: 16; // data size
1050 unsigned char data
[]; // data
1051 record
* next () { return (record
*) (((char *) this) + next_o
); }
1052 void set_next ( record
* nxt
) { next_o
= ((char *) nxt
) - ((char *) this); }
1053 unsigned char *name () { return (unsigned char *)
1054 (((char *) this) - complen
); }
1057 record
* anptr
= NULL
, * prevptr
= NULL
, * curptr
;
1058 int i
, alias_count
= 0, string_size
= 0, address_count
= 0;
1059 int namelen1
= 0, address_len
= 0, antype
, anclass
, ansize
;
1062 /* Get the count of answers */
1063 ancount
= ntohs (((HEADER
*) msg
)->ancount
);
1065 /* Skip the question, it was verified by res_send */
1066 ptr
= msg
+ sizeof (HEADER
);
1067 if ((complen
= dn_skipname (ptr
, eomsg
)) < 0)
1069 /* Point to the beginning of the answer section */
1070 ptr
+= complen
+ NS_QFIXEDSZ
;
1072 /* Scan the answer records to determine the sizes */
1073 for (i
= 0; i
< ancount
; i
++, ptr
= curptr
->data
+ ansize
)
1075 if ((complen
= dn_skipname (ptr
, eomsg
)) < 0)
1078 curptr
= (record
*) (ptr
+ complen
);
1079 antype
= ntohs (curptr
->type
);
1080 anclass
= ntohs (curptr
->complen
);
1081 ansize
= ntohs (curptr
->size
);
1082 /* Class must be internet */
1083 if (anclass
!= ns_c_in
)
1086 curptr
->complen
= complen
;
1087 if ((namelen1
= dn_length1 (msg
, eomsg
, curptr
-> name())) <= 0)
1090 if (antype
== ns_t_cname
)
1093 string_size
+= namelen1
;
1095 else if (antype
== type
)
1097 ansize
= ntohs (curptr
->size
);
1098 if (ansize
!= addrsize_in
)
1100 if (address_count
== 0)
1102 address_len
= namelen1
;
1103 string_size
+= namelen1
;
1105 else if (address_len
!= namelen1
)
1109 /* Update the records */
1110 curptr
->type
= antype
; /* Host byte order */
1111 curptr
->namelen1
= namelen1
;
1113 anptr
= prevptr
= curptr
;
1116 prevptr
->set_next (curptr
);
1121 /* If there is no address, quit */
1122 if (address_count
== 0)
1129 /* Determine the total size */
1130 sz
= DWORD_round (sizeof(hostent
))
1131 + sizeof (char *) * (alias_count
+ address_count
+ 2)
1133 + address_count
* addrsize_out
;
1135 ret
= realloc_ent (sz
, (hostent
*) NULL
);
1140 set_errno (old_errno
);
1141 h_errno
= NETDB_INTERNAL
;
1145 ret
->h_addrtype
= af
;
1146 ret
->h_length
= addrsize_out
;
1147 ret
->h_aliases
= (char **) (((char *) ret
) + DWORD_round (sizeof(hostent
)));
1148 ret
->h_addr_list
= ret
->h_aliases
+ alias_count
+ 1;
1149 string_ptr
= (char *) (ret
->h_addr_list
+ address_count
+ 1);
1151 /* Rescan the answers */
1152 alias_count
= address_count
= 0;
1153 prevptr
->set_next (prevptr
+ 1);
1155 for (curptr
= anptr
; curptr
<= prevptr
; curptr
= curptr
->next ())
1157 antype
= curptr
->type
;
1158 if (antype
== ns_t_cname
)
1160 dn_expand (msg
, eomsg
, curptr
->name (), string_ptr
, curptr
->namelen1
);
1161 ret
->h_aliases
[alias_count
++] = string_ptr
;
1162 string_ptr
+= curptr
->namelen1
;
1166 if (address_count
== 0)
1168 dn_expand (msg
, eomsg
, curptr
->name (), string_ptr
,
1170 ret
->h_name
= string_ptr
;
1171 string_ptr
+= curptr
->namelen1
;
1173 ret
->h_addr_list
[address_count
++] = string_ptr
;
1174 if (addrsize_in
!= addrsize_out
)
1176 memcpy4to6 (string_ptr
, curptr
->data
);
1177 ret
->h_addrtype
= AF_INET6
;
1180 memcpy (string_ptr
, curptr
->data
, addrsize_in
);
1181 string_ptr
+= addrsize_out
;
1187 ret
->h_aliases
[alias_count
] = NULL
;
1188 ret
->h_addr_list
[address_count
] = NULL
;
1194 /* Hopefully message corruption errors are temporary.
1195 Should it be NO_RECOVERY ? */
1196 h_errno
= TRY_AGAIN
;
1200 /* gethostbyname2: GNU extension */
1201 extern "C" struct hostent
*
1202 gethostbyname2 (const char *name
, int af
)
1204 hostent
*res
= NULL
;
1208 if (!(_res
.options
& RES_INIT
))
1211 bool v4to6
= _res
.options
& RES_USE_INET6
;
1212 int type
, addrsize_in
, addrsize_out
;
1217 addrsize_in
= NS_INADDRSZ
;
1218 addrsize_out
= (v4to6
) ? NS_IN6ADDRSZ
: NS_INADDRSZ
;
1222 addrsize_in
= addrsize_out
= NS_IN6ADDRSZ
;
1226 set_errno (EAFNOSUPPORT
);
1227 h_errno
= NETDB_INTERNAL
;
1231 h_errno
= NETDB_SUCCESS
;
1232 res
= gethostby_specials (name
, af
, addrsize_in
, addrsize_out
);
1233 if ((res
== NULL
) && (h_errno
== NETDB_SUCCESS
))
1234 res
= gethostby_helper (name
, af
, type
, addrsize_in
, addrsize_out
);
1236 __except (EFAULT
) {}
1241 /* exported as accept: POSIX.1-2001, POSIX.1-2008, SVr4, 4.4BSD */
1243 cygwin_accept (int fd
, struct sockaddr
*peer
, socklen_t
*len
)
1247 pthread_testcancel ();
1251 fhandler_socket
*fh
= get (fd
);
1253 res
= fh
->accept4 (peer
, len
,
1254 fh
->is_nonblocking () ? SOCK_NONBLOCK
: 0);
1256 __except (EFAULT
) {}
1258 syscall_printf ("%R = accept(%d, %p, %p)", res
, fd
, peer
, len
);
1262 /* accept4: GNU extension */
1264 accept4 (int fd
, struct sockaddr
*peer
, socklen_t
*len
, int flags
)
1268 pthread_testcancel ();
1272 fhandler_socket
*fh
= get (fd
);
1275 if ((flags
& ~(SOCK_NONBLOCK
| SOCK_CLOEXEC
)) != 0)
1278 res
= fh
->accept4 (peer
, len
, flags
);
1280 __except (EFAULT
) {}
1282 syscall_printf ("%R = accept4(%d, %p, %p, %y)", res
, fd
, peer
, len
, flags
);
1286 /* exported as bind: POSIX.1-2001, POSIX.1-2008, SVr4, 4.4BSD */
1288 cygwin_bind (int fd
, const struct sockaddr
*my_addr
, socklen_t addrlen
)
1294 fhandler_socket
*fh
= get (fd
);
1296 res
= fh
->bind (my_addr
, addrlen
);
1298 __except (EFAULT
) {}
1300 syscall_printf ("%R = bind(%d, %p, %d)", res
, fd
, my_addr
, addrlen
);
1304 /* exported as getsockname: POSIX.1-2001, POSIX.1-2008, SVr4, 4.4BSD */
1306 cygwin_getsockname (int fd
, struct sockaddr
*addr
, socklen_t
*namelen
)
1312 fhandler_socket
*fh
= get (fd
);
1314 res
= fh
->getsockname (addr
, namelen
);
1316 __except (EFAULT
) {}
1318 syscall_printf ("%R =getsockname (%d, %p, %p)", res
, fd
, addr
, namelen
);
1322 /* exported as listen: POSIX.1-2001, POSIX.1-2008, SVr4, 4.4BSD */
1324 cygwin_listen (int fd
, int backlog
)
1330 fhandler_socket
*fh
= get (fd
);
1332 res
= fh
->listen (backlog
);
1334 __except (EFAULT
) {}
1336 syscall_printf ("%R = listen(%d, %d)", res
, fd
, backlog
);
1340 /* exported as shutdown: POSIX.1-2001, POSIX.1-2008, SVr4, 4.4BSD */
1342 cygwin_shutdown (int fd
, int how
)
1346 fhandler_socket
*fh
= get (fd
);
1348 res
= fh
->shutdown (how
);
1349 syscall_printf ("%R = shutdown(%d, %d)", res
, fd
, how
);
1353 /* exported as hstrerror: BSD 4.3 */
1354 extern "C" const char *
1355 cygwin_hstrerror (int err
)
1359 for (i
= 0; host_errmap
[i
].e
!= 0; ++i
)
1360 if (err
== host_errmap
[i
].e
)
1363 return host_errmap
[i
].s
;
1366 /* exported as herror: BSD 4.3 */
1368 cygwin_herror (const char *s
)
1372 if (cygheap
->fdtab
.not_open (2))
1377 write (2, s
, strlen (s
));
1381 const char *h_errstr
= cygwin_hstrerror (h_errno
);
1386 case NETDB_INTERNAL
:
1387 h_errstr
= "Resolver internal error";
1390 h_errstr
= "Resolver error 0 (no error)";
1393 h_errstr
= "Unknown resolver error";
1396 write (2, h_errstr
, strlen (h_errstr
));
1399 __except (NO_ERROR
) {}
1403 /* exported as getpeername: POSIX.1-2001, POSIX.1-2008, SVr4, 4.4BSD */
1405 cygwin_getpeername (int fd
, struct sockaddr
*name
, socklen_t
*len
)
1408 fhandler_socket
*fh
= NULL
;
1414 res
= fh
->getpeername (name
, len
);
1416 __except (EFAULT
) {}
1418 syscall_printf ("%R = getpeername(%d)", res
, fd
);
1422 /* exported as recv: POSIX.1-2001, POSIX.1-2008, SVr4, 4.4BSD */
1424 cygwin_recv (int fd
, void *buf
, size_t len
, int flags
)
1428 pthread_testcancel ();
1432 fhandler_socket
*fh
= get (fd
);
1434 /* Originally we shortcircuited here if res == 0.
1435 Allow 0 bytes buffer. This is valid in POSIX and handled in
1436 fhandler_socket::recv_internal. If we shortcircuit, we fail
1437 to deliver valid error conditions. */
1438 res
= fh
->recvfrom (buf
, len
, flags
, NULL
, NULL
);
1440 __except (EFAULT
) {}
1442 syscall_printf ("%lR = recv(%d, %p, %ld, %y)", res
, fd
, buf
, len
, flags
);
1446 /* exported as send: POSIX.1-2001, POSIX.1-2008, SVr4, 4.4BSD */
1448 cygwin_send (int fd
, const void *buf
, size_t len
, int flags
)
1452 pthread_testcancel ();
1456 fhandler_socket
*fh
= get (fd
);
1458 res
= fh
->sendto (buf
, len
, flags
, NULL
, 0);
1462 syscall_printf ("%lR = send(%d, %p, %ld, %y)", res
, fd
, buf
, len
, flags
);
1466 /* Fill out an ifconf struct. */
1469 get_adapters_addresses (PIP_ADAPTER_ADDRESSES
*pa_ret
, ULONG family
)
1471 DWORD ret
, size
= 0;
1472 PIP_ADAPTER_ADDRESSES pa0
= NULL
;
1475 return GetAdaptersAddresses (family
, GAA_FLAG_INCLUDE_PREFIX
1476 | GAA_FLAG_INCLUDE_ALL_INTERFACES
,
1480 ret
= GetAdaptersAddresses (family
, GAA_FLAG_INCLUDE_PREFIX
1481 | GAA_FLAG_INCLUDE_ALL_INTERFACES
,
1483 if (ret
== ERROR_BUFFER_OVERFLOW
1484 && !(pa0
= (PIP_ADAPTER_ADDRESSES
) realloc (pa0
, size
)))
1487 while (ret
== ERROR_BUFFER_OVERFLOW
);
1490 if (ret
!= ERROR_SUCCESS
)
1498 return ret
== ERROR_SUCCESS
|| (!pa_ret
&& ret
== ERROR_BUFFER_OVERFLOW
);
1502 get_routedst (DWORD if_index
)
1504 PMIB_IPFORWARDTABLE pift
;
1506 if (GetIpForwardTable (NULL
, &size
, FALSE
) == ERROR_INSUFFICIENT_BUFFER
1507 && (pift
= (PMIB_IPFORWARDTABLE
) alloca (size
))
1508 && GetIpForwardTable (pift
, &size
, FALSE
) == NO_ERROR
)
1509 for (DWORD i
= 0; i
< pift
->dwNumEntries
; ++i
)
1511 if (pift
->table
[i
].dwForwardIfIndex
== if_index
1512 && pift
->table
[i
].dwForwardMask
== INADDR_BROADCAST
)
1513 return pift
->table
[i
].dwForwardDest
;
1519 struct ifaddrs ifa_ifa
;
1520 char ifa_name
[IFNAMSIZ
];
1521 struct sockaddr_storage ifa_addr
;
1522 struct sockaddr_storage ifa_brddstaddr
;
1523 struct sockaddr_storage ifa_netmask
;
1524 struct ifaddrs_hwdata ifa_hwdata
;
1528 get_flags (PIP_ADAPTER_ADDRESSES pap
)
1530 unsigned int flags
= IFF_UP
;
1531 if (pap
->IfType
== IF_TYPE_SOFTWARE_LOOPBACK
)
1532 flags
|= IFF_LOOPBACK
;
1533 else if (pap
->IfType
== IF_TYPE_PPP
1534 || pap
->IfType
== IF_TYPE_SLIP
)
1535 flags
|= IFF_POINTOPOINT
| IFF_NOARP
;
1536 if (!(pap
->Flags
& IP_ADAPTER_NO_MULTICAST
))
1537 flags
|= IFF_MULTICAST
;
1538 if (pap
->OperStatus
== IfOperStatusUp
1539 || pap
->OperStatus
== IfOperStatusUnknown
)
1540 flags
|= IFF_RUNNING
;
1541 if (pap
->OperStatus
!= IfOperStatusLowerLayerDown
)
1542 flags
|= IFF_LOWER_UP
;
1543 if (pap
->OperStatus
== IfOperStatusDormant
)
1544 flags
|= IFF_DORMANT
;
1549 get_ipv4fromreg_ipcnt (const char *name
)
1551 WCHAR regkey
[256], *c
;
1553 c
= wcpcpy (regkey
, L
"Tcpip\\Parameters\\Interfaces\\");
1554 sys_mbstowcs (c
, 220, name
);
1555 if (!NT_SUCCESS (RtlCheckRegistryKey (RTL_REGISTRY_SERVICES
, regkey
)))
1560 UNICODE_STRING uipa
= { 0, 0, NULL
};
1561 RTL_QUERY_REGISTRY_TABLE tab
[3] = {
1562 { NULL
, RTL_QUERY_REGISTRY_DIRECT
| RTL_QUERY_REGISTRY_NOSTRING
,
1563 L
"EnableDHCP", &dhcp
, REG_NONE
, NULL
, 0 },
1564 { NULL
, RTL_QUERY_REGISTRY_DIRECT
| RTL_QUERY_REGISTRY_NOEXPAND
,
1565 L
"IPAddress", &uipa
, REG_NONE
, NULL
, 0 },
1566 { NULL
, 0, NULL
, NULL
, 0, NULL
, 0 }
1569 /* If DHCP is used, we have only one address. */
1570 if (NT_SUCCESS (RtlQueryRegistryValues (RTL_REGISTRY_SERVICES
, regkey
, tab
,
1575 for (ifs
= 0, c
= uipa
.Buffer
; *c
; c
+= wcslen (c
) + 1)
1577 RtlFreeUnicodeString (&uipa
);
1583 get_ipv4fromreg (struct ifall
*ifp
, const char *name
, DWORD idx
)
1585 WCHAR regkey
[256], *c
;
1586 bool got_addr
= false, got_mask
= false;
1588 c
= wcpcpy (regkey
, L
"Tcpip\\Parameters\\Interfaces\\");
1589 sys_mbstowcs (c
, 220, name
);
1590 if (!NT_SUCCESS (RtlCheckRegistryKey (RTL_REGISTRY_SERVICES
, regkey
)))
1595 UNICODE_STRING udipa
= { 0, 0, NULL
};
1596 UNICODE_STRING udsub
= { 0, 0, NULL
};
1597 UNICODE_STRING uipa
= { 0, 0, NULL
};
1598 UNICODE_STRING usub
= { 0, 0, NULL
};
1599 RTL_QUERY_REGISTRY_TABLE tab
[6] = {
1600 { NULL
, RTL_QUERY_REGISTRY_DIRECT
| RTL_QUERY_REGISTRY_NOSTRING
,
1601 L
"EnableDHCP", &dhcp
, REG_NONE
, NULL
, 0 },
1602 { NULL
, RTL_QUERY_REGISTRY_DIRECT
| RTL_QUERY_REGISTRY_NOEXPAND
,
1603 L
"DhcpIPAddress", &udipa
, REG_NONE
, NULL
, 0 },
1604 { NULL
, RTL_QUERY_REGISTRY_DIRECT
| RTL_QUERY_REGISTRY_NOEXPAND
,
1605 L
"DhcpSubnetMask", &udsub
, REG_NONE
, NULL
, 0 },
1606 { NULL
, RTL_QUERY_REGISTRY_DIRECT
| RTL_QUERY_REGISTRY_NOEXPAND
,
1607 L
"IPAddress", &uipa
, REG_NONE
, NULL
, 0 },
1608 { NULL
, RTL_QUERY_REGISTRY_DIRECT
| RTL_QUERY_REGISTRY_NOEXPAND
,
1609 L
"SubnetMask", &usub
, REG_NONE
, NULL
, 0 },
1610 { NULL
, 0, NULL
, NULL
, 0, NULL
, 0 }
1613 if (NT_SUCCESS (RtlQueryRegistryValues (RTL_REGISTRY_SERVICES
, regkey
, tab
,
1616 # define addr ((struct sockaddr_in *) &ifp->ifa_addr)
1617 # define mask ((struct sockaddr_in *) &ifp->ifa_netmask)
1618 # define brdc ((struct sockaddr_in *) &ifp->ifa_brddstaddr)
1619 # define inet_uton(u, a) \
1622 sys_wcstombs (t, 64, (u)); \
1623 cygwin_inet_pton (AF_INET, t, (a)); \
1625 /* If DHCP is used, we have only one address. */
1630 inet_uton (udipa
.Buffer
, &addr
->sin_addr
);
1635 inet_uton (udsub
.Buffer
, &mask
->sin_addr
);
1643 for (ifs
= 0, c
= uipa
.Buffer
; *c
&& ifs
< idx
;
1644 c
+= wcslen (c
) + 1)
1648 inet_uton (c
, &addr
->sin_addr
);
1654 for (ifs
= 0, c
= usub
.Buffer
; *c
&& ifs
< idx
;
1655 c
+= wcslen (c
) + 1)
1659 inet_uton (c
, &mask
->sin_addr
);
1665 ifp
->ifa_ifa
.ifa_addr
= (struct sockaddr
*) addr
;
1667 ifp
->ifa_ifa
.ifa_netmask
= (struct sockaddr
*) mask
;
1668 if (ifp
->ifa_ifa
.ifa_flags
& IFF_BROADCAST
)
1669 brdc
->sin_addr
.s_addr
= (addr
->sin_addr
.s_addr
1670 & mask
->sin_addr
.s_addr
)
1671 | ~mask
->sin_addr
.s_addr
;
1677 RtlFreeUnicodeString (&udipa
);
1679 RtlFreeUnicodeString (&udsub
);
1681 RtlFreeUnicodeString (&uipa
);
1683 RtlFreeUnicodeString (&usub
);
1688 get_friendlyname (struct ifall
*ifp
, PIP_ADAPTER_ADDRESSES pap
)
1690 struct ifreq_frndlyname
*iff
= (struct ifreq_frndlyname
*)
1691 &ifp
->ifa_hwdata
.ifa_frndlyname
;
1692 iff
->ifrf_len
= sys_wcstombs (iff
->ifrf_friendlyname
,
1693 IFRF_FRIENDLYNAMESIZ
,
1694 pap
->FriendlyName
) + 1;
1698 get_hwaddr (struct ifall
*ifp
, PIP_ADAPTER_ADDRESSES pap
)
1700 for (UINT i
= 0; i
< IFHWADDRLEN
; ++i
)
1701 if (i
>= pap
->PhysicalAddressLength
)
1702 ifp
->ifa_hwdata
.ifa_hwaddr
.sa_data
[i
] = '\0';
1704 ifp
->ifa_hwdata
.ifa_hwaddr
.sa_data
[i
] = pap
->PhysicalAddress
[i
];
1708 * Get network interfaces. Use IP Helper function GetAdaptersAddresses.
1710 static struct ifall
*
1711 get_ifs (ULONG family
)
1713 PIP_ADAPTER_ADDRESSES pa0
= NULL
, pap
;
1714 PIP_ADAPTER_UNICAST_ADDRESS pua
;
1716 struct ifall
*ifret
= NULL
, *ifp
;
1717 struct sockaddr_in
*if_sin
;
1718 struct sockaddr_in6
*if_sin6
;
1720 if (!get_adapters_addresses (&pa0
, family
))
1723 for (pap
= pa0
; pap
; pap
= pap
->Next
)
1724 if (!pap
->FirstUnicastAddress
)
1726 /* FirstUnicastAddress is NULL for interfaces which are disconnected.
1727 Fetch number of configured IPv4 addresses from registry and
1728 store in an unused member of the adapter addresses structure. */
1729 pap
->Ipv6IfIndex
= get_ipv4fromreg_ipcnt (pap
->AdapterName
);
1730 cnt
+= pap
->Ipv6IfIndex
;
1732 else for (pua
= pap
->FirstUnicastAddress
; pua
; pua
= pua
->Next
)
1735 if (!(ifret
= (struct ifall
*) calloc (cnt
, sizeof (struct ifall
))))
1739 for (pap
= pa0
; pap
; pap
= pap
->Next
)
1742 if (!pap
->FirstUnicastAddress
)
1743 for (idx
= 0; idx
< pap
->Ipv6IfIndex
; ++idx
)
1746 ifp
->ifa_ifa
.ifa_next
= (struct ifaddrs
*) &ifp
[1].ifa_ifa
;
1747 /* Interface name */
1750 __small_sprintf (ifp
->ifa_name
, "%s:%u", pap
->AdapterName
, idx
);
1752 strcpy (ifp
->ifa_name
, pap
->AdapterName
);
1753 ifp
->ifa_ifa
.ifa_name
= ifp
->ifa_name
;
1755 ifp
->ifa_ifa
.ifa_flags
= get_flags (pap
);
1756 if (pap
->IfType
!= IF_TYPE_PPP
1757 && pap
->IfType
!= IF_TYPE_SOFTWARE_LOOPBACK
)
1758 ifp
->ifa_ifa
.ifa_flags
|= IFF_BROADCAST
;
1760 ifp
->ifa_addr
.ss_family
= AF_INET
;
1761 ifp
->ifa_ifa
.ifa_addr
= NULL
;
1762 /* Broadcast/Destination address */
1763 ifp
->ifa_brddstaddr
.ss_family
= AF_INET
;
1764 ifp
->ifa_ifa
.ifa_dstaddr
= NULL
;
1766 ifp
->ifa_netmask
.ss_family
= AF_INET
;
1767 ifp
->ifa_ifa
.ifa_netmask
= NULL
;
1768 /* Try to fetch real IPv4 address information from registry. */
1769 get_ipv4fromreg (ifp
, pap
->AdapterName
, idx
);
1770 /* Hardware address */
1771 get_hwaddr (ifp
, pap
);
1773 ifp
->ifa_hwdata
.ifa_metric
= 1;
1775 ifp
->ifa_hwdata
.ifa_mtu
= pap
->Mtu
;
1776 /* Interface index */
1777 ifp
->ifa_hwdata
.ifa_ifindex
= pap
->IfIndex
;
1779 get_friendlyname (ifp
, pap
);
1780 /* Let ifa_data member point to "ifaddrs_hwdata" data. */
1781 ifp
->ifa_ifa
.ifa_data
= &ifp
->ifa_hwdata
;
1785 for (idx
= 0, pua
= pap
->FirstUnicastAddress
; pua
; pua
= pua
->Next
)
1787 struct sockaddr
*sa
= (struct sockaddr
*) pua
->Address
.lpSockaddr
;
1788 # define sin ((struct sockaddr_in *) sa)
1789 # define sin6 ((struct sockaddr_in6 *) sa)
1790 size_t sa_size
= (sa
->sa_family
== AF_INET6
1791 ? sizeof *sin6
: sizeof *sin
);
1793 ifp
->ifa_ifa
.ifa_next
= (struct ifaddrs
*) &ifp
[1].ifa_ifa
;
1794 /* Interface name */
1795 if (sa
->sa_family
== AF_INET
&& idx
)
1796 __small_sprintf (ifp
->ifa_name
, "%s:%u", pap
->AdapterName
, idx
);
1798 strcpy (ifp
->ifa_name
, pap
->AdapterName
);
1799 if (sa
->sa_family
== AF_INET
)
1801 ifp
->ifa_ifa
.ifa_name
= ifp
->ifa_name
;
1803 ifp
->ifa_ifa
.ifa_flags
= get_flags (pap
);
1804 if (sa
->sa_family
== AF_INET
1805 && pap
->IfType
!= IF_TYPE_SOFTWARE_LOOPBACK
1806 && pap
->IfType
!= IF_TYPE_PPP
)
1807 ifp
->ifa_ifa
.ifa_flags
|= IFF_BROADCAST
;
1809 memcpy (&ifp
->ifa_addr
, sa
, sa_size
);
1810 ifp
->ifa_ifa
.ifa_addr
= (struct sockaddr
*) &ifp
->ifa_addr
;
1812 int prefix
= pua
->OnLinkPrefixLength
;
1813 switch (sa
->sa_family
)
1816 if_sin
= (struct sockaddr_in
*) &ifp
->ifa_netmask
;
1817 if_sin
->sin_addr
.s_addr
= htonl (UINT32_MAX
<< (32 - prefix
));
1818 if_sin
->sin_family
= AF_INET
;
1821 if_sin6
= (struct sockaddr_in6
*) &ifp
->ifa_netmask
;
1822 for (cnt
= 0; cnt
< 4 && prefix
> 0; ++cnt
, prefix
-= 32)
1824 if_sin6
->sin6_addr
.s6_addr32
[cnt
] = UINT32_MAX
;
1826 if_sin6
->sin6_addr
.s6_addr32
[cnt
] <<= 32 - prefix
;
1828 if_sin6
->sin6_family
= AF_INET6
;
1831 ifp
->ifa_ifa
.ifa_netmask
= (struct sockaddr
*) &ifp
->ifa_netmask
;
1832 if (pap
->IfType
== IF_TYPE_PPP
)
1834 /* Destination address */
1835 if (sa
->sa_family
== AF_INET
)
1837 if_sin
= (struct sockaddr_in
*) &ifp
->ifa_brddstaddr
;
1838 if_sin
->sin_addr
.s_addr
= get_routedst (pap
->IfIndex
);
1839 if_sin
->sin_family
= AF_INET
;
1842 /* FIXME: No official way to get the dstaddr for ipv6? */
1843 memcpy (&ifp
->ifa_addr
, sa
, sa_size
);
1844 ifp
->ifa_ifa
.ifa_dstaddr
= (struct sockaddr
*)
1845 &ifp
->ifa_brddstaddr
;
1849 /* Broadcast address */
1850 if (sa
->sa_family
== AF_INET
)
1852 if_sin
= (struct sockaddr_in
*) &ifp
->ifa_brddstaddr
;
1854 ((struct sockaddr_in
*) &ifp
->ifa_netmask
)->sin_addr
.s_addr
;
1855 if_sin
->sin_addr
.s_addr
= (sin
->sin_addr
.s_addr
& mask
)
1857 if_sin
->sin_family
= AF_INET
;
1858 ifp
->ifa_ifa
.ifa_broadaddr
= (struct sockaddr
*)
1859 &ifp
->ifa_brddstaddr
;
1861 else /* No IPv6 broadcast */
1862 ifp
->ifa_ifa
.ifa_broadaddr
= NULL
;
1864 /* Hardware address */
1865 get_hwaddr (ifp
, pap
);
1867 ifp
->ifa_hwdata
.ifa_metric
= (sa
->sa_family
== AF_INET
1868 ? pap
->Ipv4Metric
: pap
->Ipv6Metric
);
1870 ifp
->ifa_hwdata
.ifa_mtu
= pap
->Mtu
;
1871 /* Interface index */
1872 ifp
->ifa_hwdata
.ifa_ifindex
= pap
->IfIndex
;
1874 get_friendlyname (ifp
, pap
);
1875 /* Let ifa_data member point to "ifaddrs_hwdata" data. */
1876 ifp
->ifa_ifa
.ifa_data
= &ifp
->ifa_hwdata
;
1882 /* Since every entry is set to the next entry, the last entry points to an
1883 invalid next entry now. Fix it retroactively. */
1885 ifp
[-1].ifa_ifa
.ifa_next
= NULL
;
1894 getifaddrs (struct ifaddrs
**ifap
)
1902 ifp
= get_ifs (AF_UNSPEC
);
1903 *ifap
= &ifp
->ifa_ifa
;
1904 return ifp
? 0 : -1;
1908 freeifaddrs (struct ifaddrs
*ifp
)
1915 get_ifconf (struct ifconf
*ifc
, unsigned int what
)
1919 /* Ensure we have space for at least one struct ifreqs, fail if not. */
1920 if (ifc
->ifc_len
< (int) sizeof (struct ifreq
))
1926 struct ifall
*ifret
, *ifp
;
1927 ifret
= get_ifs (AF_INET
);
1931 struct sockaddr_in
*sin
;
1932 struct ifreq
*ifr
= ifc
->ifc_req
;
1934 for (ifp
= ifret
; ifp
; ifp
= (struct ifall
*) ifp
->ifa_ifa
.ifa_next
)
1937 strcpy (ifr
->ifr_name
, ifp
->ifa_name
);
1941 ifr
->ifr_flags
= ifp
->ifa_ifa
.ifa_flags
;
1945 sin
= (struct sockaddr_in
*) &ifr
->ifr_addr
;
1946 memcpy (sin
, &ifp
->ifa_addr
, sizeof *sin
);
1948 case SIOCGIFNETMASK
:
1949 sin
= (struct sockaddr_in
*) &ifr
->ifr_netmask
;
1950 memcpy (sin
, &ifp
->ifa_netmask
, sizeof *sin
);
1952 case SIOCGIFDSTADDR
:
1953 sin
= (struct sockaddr_in
*) &ifr
->ifr_dstaddr
;
1954 if (ifp
->ifa_ifa
.ifa_flags
& IFF_POINTOPOINT
)
1955 memcpy (sin
, &ifp
->ifa_brddstaddr
, sizeof *sin
);
1956 else /* Return addr as on Linux. */
1957 memcpy (sin
, &ifp
->ifa_addr
, sizeof *sin
);
1959 case SIOCGIFBRDADDR
:
1960 sin
= (struct sockaddr_in
*) &ifr
->ifr_broadaddr
;
1961 if (!(ifp
->ifa_ifa
.ifa_flags
& IFF_POINTOPOINT
))
1962 memcpy (sin
, &ifp
->ifa_brddstaddr
, sizeof *sin
);
1965 sin
->sin_addr
.s_addr
= INADDR_ANY
;
1966 sin
->sin_family
= AF_INET
;
1971 memcpy (&ifr
->ifr_hwaddr
, &ifp
->ifa_hwdata
.ifa_hwaddr
,
1972 sizeof ifr
->ifr_hwaddr
);
1975 ifr
->ifr_metric
= ifp
->ifa_hwdata
.ifa_metric
;
1978 ifr
->ifr_mtu
= ifp
->ifa_hwdata
.ifa_mtu
;
1981 ifr
->ifr_ifindex
= ifp
->ifa_hwdata
.ifa_ifindex
;
1983 case SIOCGIFFRNDLYNAM
:
1984 memcpy (ifr
->ifr_frndlyname
, &ifp
->ifa_hwdata
.ifa_frndlyname
,
1985 sizeof (struct ifreq_frndlyname
));
1987 if ((caddr_t
) ++ifr
>
1988 ifc
->ifc_buf
+ ifc
->ifc_len
- sizeof (struct ifreq
))
1991 /* Set the correct length */
1992 ifc
->ifc_len
= cnt
* sizeof (struct ifreq
);
1996 __except (EFAULT
) {}
2002 cygwin_if_nametoindex (const char *name
)
2004 PIP_ADAPTER_ADDRESSES pa0
= NULL
, pap
;
2005 if (get_adapters_addresses (&pa0
, AF_UNSPEC
))
2006 for (pap
= pa0
; pap
; pap
= pap
->Next
)
2007 if (strcmp (name
, pap
->AdapterName
) == 0)
2010 return pap
->IfIndex
;
2018 cygwin_if_indextoname (unsigned ifindex
, char *ifname
)
2020 if (ifindex
== 0 || ifname
== NULL
)
2025 PIP_ADAPTER_ADDRESSES pa0
= NULL
, pap
;
2026 if (get_adapters_addresses (&pa0
, AF_UNSPEC
))
2027 for (pap
= pa0
; pap
; pap
= pap
->Next
)
2028 if (ifindex
== pap
->IfIndex
)
2030 strcpy (ifname
, pap
->AdapterName
);
2040 extern "C" struct if_nameindex
*
2043 PIP_ADAPTER_ADDRESSES pa0
= NULL
, pap
;
2044 struct if_nameindex
*iflist
= NULL
;
2045 char (*ifnamelist
)[IF_NAMESIZE
];
2049 if (get_adapters_addresses (&pa0
, AF_UNSPEC
))
2052 for (pap
= pa0
; pap
; pap
= pap
->Next
)
2054 iflist
= (struct if_nameindex
*)
2055 malloc ((cnt
+ 1) * sizeof (struct if_nameindex
)
2056 + cnt
* IF_NAMESIZE
);
2058 set_errno (ENOBUFS
);
2061 ifnamelist
= (char (*)[IF_NAMESIZE
]) (iflist
+ cnt
+ 1);
2062 for (pap
= pa0
, cnt
= 0; pap
; pap
= pap
->Next
)
2064 for (int i
= 0; i
< cnt
; ++i
)
2065 if (iflist
[i
].if_index
2066 == (pap
->Ipv6IfIndex
?: pap
->IfIndex
))
2068 iflist
[cnt
].if_index
= pap
->Ipv6IfIndex
?: pap
->IfIndex
;
2069 strcpy (iflist
[cnt
].if_name
= ifnamelist
[cnt
],
2071 /* See comment in if_indextoname. */
2072 if (pap
->IfIndex
== 1 && pap
->Ipv6IfIndex
== 0)
2073 for (PIP_ADAPTER_ADDRESSES pap2
= pa0
;
2076 if (pap2
->Ipv6IfIndex
== 1)
2078 strcpy (ifnamelist
[cnt
], pap2
->AdapterName
);
2085 iflist
[cnt
].if_index
= 0;
2086 iflist
[cnt
].if_name
= NULL
;
2093 __except (EFAULT
) {}
2099 if_freenameindex (struct if_nameindex
*ptr
)
2104 #define PORT_LOW (IPPORT_EFSSERVER + 1)
2105 #define PORT_HIGH (IPPORT_RESERVED - 1)
2106 #define NUM_PORTS (PORT_HIGH - PORT_LOW + 1)
2108 /* port is in host byte order */
2110 next_free_port (sa_family_t family
, in_port_t in_port
)
2115 PMIB_TCPTABLE tab4
= NULL
;
2116 PMIB_TCP6TABLE tab6
= NULL
;
2118 /* Start testing with incoming port number. */
2119 in_port_t tst_port
= in_port
;
2120 in_port_t res_port
= 0;
2125 if (family
== AF_INET
)
2126 ret
= GetTcpTable ((PMIB_TCPTABLE
) tab
, &size
, TRUE
);
2128 ret
= GetTcp6Table ((PMIB_TCP6TABLE
) tab
, &size
, TRUE
);
2130 if (ret
== ERROR_INSUFFICIENT_BUFFER
)
2131 tab
= (char *) realloc (tab
, size
);
2133 while (ret
== ERROR_INSUFFICIENT_BUFFER
);
2135 tab4
= (PMIB_TCPTABLE
) tab
;
2136 tab6
= (PMIB_TCP6TABLE
) tab
;
2138 /* dwNumEntries has offset 0 in both structs. */
2139 for (int idx
= tab4
->dwNumEntries
- 1; idx
>= 0; --idx
)
2141 if (family
== AF_INET
)
2142 tab_port
= ntohs (tab4
->table
[idx
].dwLocalPort
);
2144 tab_port
= ntohs (tab6
->table
[idx
].dwLocalPort
);
2145 /* Skip table entries with too high port number. */
2146 if (tab_port
> tst_port
)
2148 /* Is the current port number free? */
2149 if (tab_port
< tst_port
)
2151 res_port
= tst_port
;
2154 /* Decrement port and handle underflow of the reserved area. */
2155 if (--tst_port
< PORT_LOW
)
2157 tst_port
= PORT_HIGH
;
2158 idx
= tab4
->dwNumEntries
;
2160 /* Check if we're round to the incoming port. */
2161 if (tst_port
== in_port
)
2169 cygwin_bindresvport_sa (int fd
, struct sockaddr
*sa
)
2171 struct sockaddr_storage sst
;
2172 struct sockaddr_in
*sin
= NULL
;
2173 struct sockaddr_in6
*sin6
= NULL
;
2176 LONG port
, next_port
;
2180 fhandler_socket
*fh
= get (fd
);
2186 sa
= (struct sockaddr
*) &sst
;
2187 memset (&sst
, 0, sizeof sst
);
2188 sa
->sa_family
= fh
->get_addr_family ();
2190 else if (sa
->sa_family
!= fh
->get_addr_family ())
2192 set_errno (EPFNOSUPPORT
);
2196 switch (sa
->sa_family
)
2199 salen
= sizeof (struct sockaddr_in
);
2200 sin
= (struct sockaddr_in
*) sa
;
2203 salen
= sizeof (struct sockaddr_in6
);
2204 sin6
= (struct sockaddr_in6
*) sa
;
2207 set_errno (EPFNOSUPPORT
);
2211 /* Originally we tried to use the incoming port number first here,
2212 but that may lead to EADDRINUSE scenarios when calling bindresvport
2213 on the client side. So we ignore any port value that the caller
2214 supplies, just like glibc. */
2216 /* Note that repeating this loop NUM_PORTS times is arbitrary. The
2217 job is mainly done by next_free_port() but it doesn't cover bound
2218 sockets. And calling and checking GetTcpTable and subsequently
2219 calling bind is inevitably racy. We have to continue if bind fails
2221 for (int i
= 0; i
< NUM_PORTS
; i
++)
2223 while ((port
= InterlockedExchange (
2224 &cygwin_shared
->last_used_bindresvport
, -1)) == -1)
2227 if (next_port
== 0 || --next_port
< PORT_LOW
)
2228 next_port
= PORT_HIGH
;
2229 /* Returns 0 if no reserved port is free. */
2230 next_port
= next_free_port (sa
->sa_family
, next_port
);
2233 InterlockedExchange (&cygwin_shared
->last_used_bindresvport
, port
);
2236 set_errno (EADDRINUSE
);
2239 if (sa
->sa_family
== AF_INET6
)
2240 sin6
->sin6_port
= htons (port
);
2242 sin
->sin_port
= htons (port
);
2243 if (!(ret
= fh
->bind (sa
, salen
)))
2245 if (get_errno () != EADDRINUSE
&& get_errno () != EINVAL
)
2250 __except (EFAULT
) {}
2256 cygwin_bindresvport (int fd
, struct sockaddr_in
*sin
)
2258 if (sin
&& sin
->sin_family
!= AF_INET
)
2260 set_errno (EAFNOSUPPORT
);
2263 return cygwin_bindresvport_sa (fd
, (struct sockaddr
*) sin
);
2266 /* socketpair: POSIX.1-2001, POSIX.1-2008, 4.4BSD. */
2268 socketpair (int af
, int type
, int protocol
, int sv
[2])
2272 fhandler_socket
*fh_in
, *fh_out
;
2274 int flags
= type
& _SOCK_FLAG_MASK
;
2275 type
&= ~_SOCK_FLAG_MASK
;
2277 debug_printf ("socket (%d, %d (flags %y), %d)", af
, type
, flags
, protocol
);
2282 #ifndef __WITH_AF_UNIX
2286 dev
= (af
== AF_LOCAL
) ? af_local_dev
: af_unix_dev
;
2287 #endif /* __WITH_AF_UNIX */
2290 set_errno (EAFNOSUPPORT
);
2294 if ((flags
& ~(SOCK_NONBLOCK
| SOCK_CLOEXEC
)) != 0)
2301 cygheap_fdnew fd_in
;
2305 cygheap_fdnew
fd_out (fd_in
, false);
2309 fh_in
= reinterpret_cast<fhandler_socket
*> (build_fh_dev (*dev
));
2310 fh_out
= reinterpret_cast<fhandler_socket
*> (build_fh_dev (*dev
));
2312 && fh_in
->socketpair (af
, type
, protocol
, flags
, fh_out
) == 0)
2317 set_std_handle (fd_in
);
2319 set_std_handle (fd_out
);
2326 __except (EFAULT
) {}
2337 syscall_printf ("%R = socketpair(...)", res
);
2341 /* sethostent: POSIX.1-2001 */
2347 /* endhostent: POSIX.1-2001 */
2353 /* exported as recvmsg: POSIX.1-2001, POSIX.1-2008, 4.4BSD */
2355 cygwin_recvmsg (int fd
, struct msghdr
*msg
, int flags
)
2359 pthread_testcancel ();
2363 fhandler_socket
*fh
= get (fd
);
2366 res
= check_iovec_for_read (msg
->msg_iov
, msg
->msg_iovlen
);
2367 /* Originally we shortcircuited here if res == 0.
2368 Allow 0 bytes buffer. This is valid in POSIX and handled in
2369 fhandler_socket::recv_internal. If we shortcircuit, we fail
2370 to deliver valid error conditions and peer address. */
2372 res
= fh
->recvmsg (msg
, flags
);
2380 syscall_printf ("%lR = recvmsg(%d, %p, %y)", res
, fd
, msg
, flags
);
2384 /* exported as sendmsg: POSIX.1-2001, POSIX.1-2008, 4.4BSD */
2386 cygwin_sendmsg (int fd
, const struct msghdr
*msg
, int flags
)
2390 pthread_testcancel ();
2394 fhandler_socket
*fh
= get (fd
);
2397 res
= check_iovec_for_write (msg
->msg_iov
, msg
->msg_iovlen
);
2399 res
= fh
->sendmsg (msg
, flags
);
2407 syscall_printf ("%lR = sendmsg(%d, %p, %y)", res
, fd
, msg
, flags
);
2411 /* This is from the BIND 4.9.4 release, modified to compile by itself */
2413 /* Copyright (c) 1996 by Internet Software Consortium.
2415 * Permission to use, copy, modify, and distribute this software for any
2416 * purpose with or without fee is hereby granted, provided that the above
2417 * copyright notice and this permission notice appear in all copies.
2419 * THE SOFTWARE IS PROVIDED "AS IS" AND INTERNET SOFTWARE CONSORTIUM DISCLAIMS
2420 * ALL WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES
2421 * OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL INTERNET SOFTWARE
2422 * CONSORTIUM BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL
2423 * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR
2424 * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS
2425 * ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS
2430 * inet_pton4(src, dst)
2431 * like inet_aton() but without all the hexadecimal and shorthand.
2433 * 1 if `src' is a valid dotted quad, else 0.
2435 * does not touch `dst' unless it's returning 1.
2440 inet_pton4 (const char *src
, u_int8_t
*dst
)
2442 static const char digits
[] = "0123456789";
2443 int saw_digit
, octets
, ch
;
2444 u_int8_t tmp
[INADDRSZ
], *tp
;
2449 while ((ch
= *src
++) != '\0')
2453 if ((pch
= strchr(digits
, ch
)) != NULL
)
2455 u_int32_t ret
= *tp
* 10 + (pch
- digits
);
2467 else if (ch
== '.' && saw_digit
)
2480 memcpy(dst
, tmp
, INADDRSZ
);
2485 * inet_pton6(src, dst)
2486 * convert presentation level address to network order binary form.
2488 * 1 if `src' is a valid [RFC1884 2.2] address, else 0.
2490 * (1) does not touch `dst' unless it's returning 1.
2491 * (2) :: in a full address is silently ignored.
2493 * inspired by Mark Andrews.
2498 inet_pton6 (const char *src
, u_int8_t
*dst
)
2500 static const char xdigits_l
[] = "0123456789abcdef",
2501 xdigits_u
[] = "0123456789ABCDEF";
2502 u_int8_t tmp
[IN6ADDRSZ
], *tp
, *endp
, *colonp
;
2503 const char *xdigits
, *curtok
;
2507 memset((tp
= tmp
), 0, IN6ADDRSZ
);
2508 endp
= tp
+ IN6ADDRSZ
;
2510 /* Leading :: requires some special handling. */
2517 while ((ch
= *src
++) != '\0')
2521 if ((pch
= strchr((xdigits
= xdigits_l
), ch
)) == NULL
)
2522 pch
= strchr((xdigits
= xdigits_u
), ch
);
2526 val
|= (pch
- xdigits
);
2542 if (tp
+ INT16SZ
> endp
)
2544 *tp
++ = (u_int8_t
) (val
>> 8) & 0xff;
2545 *tp
++ = (u_int8_t
) val
& 0xff;
2550 if (ch
== '.' && ((tp
+ INADDRSZ
) <= endp
) && inet_pton4(curtok
, tp
) > 0)
2554 break; /* '\0' was seen by inet_pton4(). */
2560 if (tp
+ INT16SZ
> endp
)
2562 *tp
++ = (u_int8_t
) (val
>> 8) & 0xff;
2563 *tp
++ = (u_int8_t
) val
& 0xff;
2568 * Since some memmove()'s erroneously fail to handle
2569 * overlapping regions, we'll do the shift by hand.
2571 const int n
= tp
- colonp
;
2574 for (i
= 1; i
<= n
; i
++)
2576 endp
[- i
] = colonp
[n
- i
];
2584 memcpy(dst
, tmp
, IN6ADDRSZ
);
2589 * inet_pton(af, src, dst)
2590 * convert from presentation format (which usually means ASCII printable)
2591 * to network format (which is usually some kind of binary format).
2593 * 1 if the address was valid for the specified address family
2594 * 0 if the address wasn't valid (`dst' is untouched in this case)
2595 * -1 if some other error occurred (`dst' is untouched in this case, too)
2600 cygwin_inet_pton (int af
, const char *src
, void *dst
)
2605 return (inet_pton4(src
, (u_int8_t
*) dst
));
2607 return (inet_pton6(src
, (u_int8_t
*) dst
));
2609 errno
= EAFNOSUPPORT
;
2616 * inet_ntop4(src, dst, size)
2617 * format an IPv4 address, more or less like inet_ntoa()
2619 * `dst' (as a const)
2621 * (1) uses no statics
2622 * (2) takes a u_int8_t* not an in_addr as input
2627 inet_ntop4 (const u_int8_t
*src
, char *dst
, size_t size
)
2629 static const char fmt
[] = "%u.%u.%u.%u";
2630 char tmp
[sizeof "255.255.255.255"];
2632 __small_sprintf(tmp
, fmt
, src
[0], src
[1], src
[2], src
[3]);
2633 if (strlen(tmp
) > size
)
2643 * inet_ntop6(src, dst, size)
2644 * convert IPv6 binary address into presentation (printable) format
2649 inet_ntop6 (const u_int8_t
*src
, char *dst
, size_t size
)
2652 * Note that int32_t and int16_t need only be "at least" large enough
2653 * to contain a value of the specified size. On some systems, like
2654 * Crays, there is no such thing as an integer variable with 16 bits.
2655 * Keep this in mind if you think this function should have been coded
2656 * to use pointer overlays. All the world's not a VAX.
2658 char tmp
[sizeof "ffff:ffff:ffff:ffff:ffff:ffff:255.255.255.255"], *tp
;
2659 struct { int base
, len
; } best
, cur
;
2660 u_int32_t words
[IN6ADDRSZ
/ INT16SZ
];
2665 * Copy the input (bytewise) array into a wordwise array.
2666 * Find the longest run of 0x00's in src[] for :: shorthanding.
2668 memset(words
, 0, sizeof words
);
2669 for (i
= 0; i
< IN6ADDRSZ
; i
++)
2670 words
[i
/ 2] |= (src
[i
] << ((1 - (i
% 2)) << 3));
2675 for (i
= 0; i
< (IN6ADDRSZ
/ INT16SZ
); i
++)
2680 cur
.base
= i
, cur
.len
= 1;
2688 if (best
.base
== -1 || cur
.len
> best
.len
)
2696 if (best
.base
== -1 || cur
.len
> best
.len
)
2699 if (best
.base
!= -1 && best
.len
< 2)
2703 * Format the result.
2706 for (i
= 0; i
< (IN6ADDRSZ
/ INT16SZ
); i
++)
2708 /* Are we inside the best run of 0x00's? */
2709 if (best
.base
!= -1 && i
>= best
.base
&& i
< (best
.base
+ best
.len
))
2715 /* Are we following an initial run of 0x00s or any real hex? */
2718 /* Is this address an encapsulated IPv4? */
2719 if (i
== 6 && best
.base
== 0 &&
2720 (best
.len
== 6 || (best
.len
== 5 && words
[5] == 0xffff)))
2722 if (!inet_ntop4(src
+12, tp
, sizeof tmp
- (tp
- tmp
)))
2727 __small_sprintf(tp
, "%x", words
[i
]);
2731 *tp
= _tolower (*tp
);
2735 /* Was it a trailing run of 0x00's? */
2736 if (best
.base
!= -1 && (best
.base
+ best
.len
) == (IN6ADDRSZ
/ INT16SZ
))
2741 * Check for overflow, copy, and we're done.
2743 if ((size_t) (tp
- tmp
) > size
)
2753 * inet_ntop(af, src, dst, size)
2754 * convert a network format address to presentation format.
2756 * pointer to presentation format address (`dst'), or NULL (see errno).
2760 extern "C" const char *
2761 cygwin_inet_ntop (int af
, const void *src
, char *dst
, socklen_t size
)
2766 return (inet_ntop4((const u_int8_t
*) src
, dst
, size
));
2768 return (inet_ntop6((const u_int8_t
*) src
, dst
, size
));
2770 errno
= EAFNOSUPPORT
;
2776 /* Exported as freeaddrinfo: POSIX.1-2001, POSIX.1-2008, RFC 2553 */
2778 cygwin_freeaddrinfo (struct addrinfo
*addr
)
2780 struct addrinfo
*ai
, *ainext
;
2782 for (ai
= addr
; ai
!= NULL
; ai
= ainext
)
2784 if (ai
->ai_addr
!= NULL
)
2785 free (ai
->ai_addr
); /* socket address structure */
2787 if (ai
->ai_canonname
!= NULL
)
2788 free (ai
->ai_canonname
);
2790 ainext
= ai
->ai_next
; /* can't fetch ai_next after free() */
2791 free (ai
); /* the addrinfo{} itself */
2795 static struct addrinfo
*
2796 ga_dup (struct addrinfoW
*ai
, bool v4mapped
, int idn_flags
, int &err
)
2798 struct addrinfo
*nai
;
2800 if ((nai
= (struct addrinfo
*) calloc (1, sizeof (struct addrinfo
))) == NULL
)
2806 nai
->ai_family
= v4mapped
? AF_INET6
: ai
->ai_family
;
2807 nai
->ai_socktype
= ai
->ai_socktype
;
2808 nai
->ai_protocol
= ai
->ai_protocol
;
2809 if (ai
->ai_canonname
)
2812 wchar_t *canonname
= ai
->ai_canonname
;
2814 if (idn_flags
& AI_CANONIDN
)
2816 /* Map flags to equivalent IDN_* flags. */
2817 wchar_t *canonbuf
= tp
.w_get ();
2818 if (IdnToUnicode (idn_flags
>> 16, canonname
, -1,
2819 canonbuf
, NT_MAX_PATH
))
2820 canonname
= canonbuf
;
2821 else if (GetLastError () != ERROR_PROC_NOT_FOUND
)
2824 err
= EAI_IDN_ENCODE
;
2828 size_t len
= wcstombs (NULL
, canonname
, 0);
2829 if (len
== (size_t) -1)
2832 err
= EAI_IDN_ENCODE
;
2835 nai
->ai_canonname
= (char *) malloc (len
+ 1);
2836 if (!nai
->ai_canonname
)
2842 wcstombs (nai
->ai_canonname
, canonname
, len
+ 1);
2845 nai
->ai_addrlen
= v4mapped
? sizeof (struct sockaddr_in6
) : ai
->ai_addrlen
;
2846 if ((nai
->ai_addr
= (struct sockaddr
*) malloc (v4mapped
2847 ? sizeof (struct sockaddr_in6
)
2848 : ai
->ai_addrlen
)) == NULL
)
2850 if (nai
->ai_canonname
)
2851 free (nai
->ai_canonname
);
2858 struct sockaddr_in6
*in
= (struct sockaddr_in6
*) nai
->ai_addr
;
2859 in
->sin6_family
= AF_INET6
;
2860 in
->sin6_port
= ((struct sockaddr_in
*) ai
->ai_addr
)->sin_port
;
2861 in
->sin6_flowinfo
= 0;
2862 in
->sin6_addr
.s6_addr32
[0] = 0;
2863 in
->sin6_addr
.s6_addr32
[1] = 0;
2864 in
->sin6_addr
.s6_addr32
[2] = htonl (0xffff);
2865 in
->sin6_addr
.s6_addr32
[3] = ((struct sockaddr_in
*) ai
->ai_addr
)->sin_addr
.s_addr
;
2866 in
->sin6_scope_id
= 0;
2869 memcpy (nai
->ai_addr
, ai
->ai_addr
, ai
->ai_addrlen
);
2874 static struct addrinfo
*
2875 ga_duplist (struct addrinfoW
*ai
, bool v4mapped
, int idn_flags
, int &err
)
2877 struct addrinfo
*tmp
, *nai
= NULL
, *nai0
= NULL
;
2879 for (; ai
; ai
= ai
->ai_next
)
2881 /* Workaround for a Windows weirdness. If a service is supported as
2882 TCP and UDP service, GetAddrInfo does not return two entries, one
2883 for TCP, one for UDP, as on Linux. Rather, it just returns a single
2884 entry with ai_socktype and ai_protocol set to 0, kind of like a
2885 placeholder. If the service only exists as TCP or UDP service, then
2886 ai->ai_socktype is set, but ai_protocol isn't. Fix up the fields,
2887 and in case ai_socktype and ai_protocol are 0 duplicate the entry
2888 with valid values for ai_socktype and ai_protocol. */
2889 switch (ai
->ai_socktype
)
2892 if (ai
->ai_protocol
== 0)
2893 ai
->ai_protocol
= IPPROTO_TCP
;
2896 if (ai
->ai_protocol
== 0)
2897 ai
->ai_protocol
= IPPROTO_UDP
;
2900 switch (ai
->ai_protocol
)
2903 ai
->ai_socktype
= SOCK_STREAM
;
2906 ai
->ai_socktype
= SOCK_DGRAM
;
2909 ai
->ai_socktype
= SOCK_STREAM
;
2910 ai
->ai_protocol
= IPPROTO_TCP
;
2911 if (!(tmp
= ga_dup (ai
, v4mapped
, idn_flags
, err
)))
2918 ai
->ai_socktype
= SOCK_DGRAM
;
2919 ai
->ai_protocol
= IPPROTO_UDP
;
2928 if (!(tmp
= ga_dup (ai
, v4mapped
, idn_flags
, err
)))
2939 cygwin_freeaddrinfo (nai0
);
2943 /* Cygwin specific wrappers around the gai functions. */
2944 static const struct gai_errmap_t
2951 /* EAI_ADDRFAMILY */
2952 {0, "Address family for hostname not supported"},
2954 {WSATRY_AGAIN
, "Temporary failure in name resolution"},
2956 {WSAEINVAL
, "Bad value for ai_flags"},
2958 {WSANO_RECOVERY
, "Non-recoverable failure in name resolution"},
2960 {WSAEAFNOSUPPORT
, "ai_family not supported"},
2962 {WSA_NOT_ENOUGH_MEMORY
, "Memory allocation failure"},
2964 {WSANO_DATA
, "No address associated with hostname"},
2966 {WSAHOST_NOT_FOUND
, "Name or service not known"},
2968 {WSATYPE_NOT_FOUND
, "Servname not supported for ai_socktype"},
2970 {WSAESOCKTNOSUPPORT
, "ai_socktype not supported"},
2972 {0, "System error"},
2974 {0, "Invalid value for hints"},
2976 {0, "Resolved protocol is unknown"},
2978 {WSAEFAULT
, "An argument buffer overflowed"},
2979 /* EAI_IDN_ENCODE */
2980 {0, "Parameter string not correctly encoded"}
2983 /* Exported as gai_strerror: POSIX.1-2001, POSIX.1-2008 */
2984 extern "C" const char *
2985 cygwin_gai_strerror (int err
)
2987 if (err
>= 0 && err
< (int) (sizeof gai_errmap
/ sizeof *gai_errmap
))
2988 return gai_errmap
[err
].errtxt
;
2989 return "Unknown error";
2993 w32_to_gai_err (int w32_err
)
2995 if (w32_err
>= WSABASEERR
)
2996 for (unsigned i
= 0; i
< sizeof gai_errmap
/ sizeof *gai_errmap
; ++i
)
2997 if (gai_errmap
[i
].w32_errval
== w32_err
)
3002 /* Exported as getaddrinfo: POSIX.1-2001, POSIX.1-2008, RFC 2553 */
3004 cygwin_getaddrinfo (const char *hostname
, const char *servname
,
3005 const struct addrinfo
*hints
, struct addrinfo
**res
)
3009 /* Windows' getaddrinfo implementations lets all possible values
3010 in ai_flags slip through and just ignores unknown values. So we
3011 check manually here. */
3012 #define AI_IDN_MASK (AI_IDN | \
3014 AI_IDN_ALLOW_UNASSIGNED | \
3015 AI_IDN_USE_STD3_ASCII_RULES)
3016 #ifndef AI_DISABLE_IDN_ENCODING
3017 #define AI_DISABLE_IDN_ENCODING 0x80000
3021 if (hints
&& (hints
->ai_flags
3022 & ~(AI_PASSIVE
| AI_CANONNAME
| AI_NUMERICHOST
| AI_ALL
3023 | AI_NUMERICSERV
| AI_ADDRCONFIG
| AI_V4MAPPED
3025 return EAI_BADFLAGS
;
3026 /* AI_NUMERICSERV is not supported "by Microsoft providers". We just
3027 check the servname parameter by ourselves here. */
3028 if (hints
&& (hints
->ai_flags
& AI_NUMERICSERV
))
3031 if (servname
&& *servname
&& (strtoul (servname
, &p
, 10), *p
))
3035 int idn_flags
= hints
? (hints
->ai_flags
& AI_IDN_MASK
) : 0;
3039 wchar_t *whost
= NULL
, *wserv
= NULL
;
3040 struct addrinfoW whints
, *wres
;
3044 memset (&ps
, 0, sizeof ps
);
3046 whost
= tp
.w_get ();
3047 if (mbsrtowcs (whost
, &src
, NT_MAX_PATH
, &ps
) == (size_t) -1)
3048 return EAI_IDN_ENCODE
;
3051 if (idn_flags
& AI_IDN
)
3053 /* Map flags to equivalent IDN_* flags. */
3054 wchar_t *ascbuf
= tp
.w_get ();
3055 if (IdnToAscii (idn_flags
>> 16, whost
, -1, ascbuf
, NT_MAX_PATH
))
3057 else if (GetLastError () != ERROR_PROC_NOT_FOUND
)
3058 return EAI_IDN_ENCODE
;
3063 memset (&ps
, 0, sizeof ps
);
3065 wserv
= tp
.w_get ();
3066 if (mbsrtowcs (wserv
, &src
, NT_MAX_PATH
, &ps
) == (size_t) -1)
3067 return EAI_IDN_ENCODE
;
3074 /* Default settings per glibc man page. */
3075 memset (&whints
, 0, sizeof whints
);
3076 whints
.ai_family
= PF_UNSPEC
;
3077 whints
.ai_flags
= AI_V4MAPPED
| AI_ADDRCONFIG
;
3081 /* sizeof addrinfo == sizeof addrinfoW */
3082 memcpy (&whints
, hints
, sizeof whints
);
3083 whints
.ai_flags
&= ~AI_IDN_MASK
;
3084 /* ai_addrlen is socklen_t (4 bytes) in POSIX but size_t (8 bytes) in
3085 Winsock. Sert upper 4 bytes explicitely to 0 to avoid EAI_FAIL. */
3086 whints
.ai_addrlen
&= UINT32_MAX
;
3087 /* On Windows, the default behaviour is as if AI_ADDRCONFIG is set,
3088 apparently for performance reasons. To get the POSIX default
3089 behaviour, the AI_ALL flag has to be set. */
3090 if (whints
.ai_family
== PF_UNSPEC
3091 && !(whints
.ai_flags
& AI_ADDRCONFIG
))
3092 whints
.ai_flags
|= AI_ALL
;
3094 /* Disable automatic IDN conversion on W8 and later. */
3095 whints
.ai_flags
|= AI_DISABLE_IDN_ENCODING
;
3096 ret
= GetAddrInfoW (whost
, wserv
, &whints
, &wres
);
3097 /* Try to workaround an apparent shortcoming in Winsock's getaddrinfo
3098 implementation. See this link for details:
3099 https://communities.vmware.com/message/2577858#2577858 */
3100 if (ret
== WSANO_RECOVERY
&& (whints
.ai_flags
& AI_ALL
))
3102 whints
.ai_flags
&= ~AI_ALL
;
3103 ret
= GetAddrInfoW (whost
, wserv
, &whints
, &wres
);
3105 ret
= w32_to_gai_err (ret
);
3106 /* Always copy over to self-allocated memory. */
3109 *res
= ga_duplist (wres
, false, idn_flags
, ret
);
3110 FreeAddrInfoW (wres
);
3123 /* Exported as getnameinfo: POSIX.1-2001, POSIX.1-2008, RFC 2553 */
3125 cygwin_getnameinfo (const struct sockaddr
*sa
, socklen_t salen
,
3126 char *host
, size_t hostlen
, char *serv
,
3127 size_t servlen
, int flags
)
3133 /* We call GetNameInfoW with local buffers and convert to locale
3134 charset to allow RFC 3490 IDNs like glibc 2.3.4 and later. */
3135 #define NI_IDN_MASK (NI_IDN | \
3136 NI_IDN_ALLOW_UNASSIGNED | \
3137 NI_IDN_USE_STD3_ASCII_RULES)
3138 int idn_flags
= flags
& NI_IDN_MASK
;
3139 flags
&= ~NI_IDN_MASK
;
3141 wchar_t *whost
= NULL
, *wserv
= NULL
;
3142 DWORD whlen
= 0, wslen
= 0;
3144 if (host
&& hostlen
)
3146 whost
= tp
.w_get ();
3147 whlen
= NT_MAX_PATH
;
3149 if (serv
&& servlen
)
3151 wserv
= tp
.w_get ();
3152 wslen
= NT_MAX_PATH
;
3155 ret
= w32_to_gai_err (GetNameInfoW (sa
, salen
, whost
, whlen
,
3156 wserv
, wslen
, flags
));
3163 if (idn_flags
& NI_IDN
)
3165 /* Map flags to equivalent IDN_* flags. */
3166 wchar_t *idnbuf
= tp
.w_get ();
3167 if (IdnToUnicode (idn_flags
>> 16, whost
, -1,
3168 idnbuf
, NT_MAX_PATH
))
3170 else if (GetLastError () != ERROR_PROC_NOT_FOUND
)
3171 return EAI_IDN_ENCODE
;
3174 if (wcsrtombs (host
, &src
, hostlen
, NULL
) == (size_t) -1)
3175 return EAI_IDN_ENCODE
;
3177 return EAI_OVERFLOW
;
3182 if (wcsrtombs (serv
, &src
, servlen
, NULL
) == (size_t) -1)
3183 return EAI_IDN_ENCODE
;
3185 return EAI_OVERFLOW
;
3188 else if (ret
== EAI_SYSTEM
)
3189 set_winsock_errno ();
3199 /* These functions are stick to the end of this file so that the
3200 optimization in asm/byteorder.h can be used even here in net.cc. */
3207 /* htonl: POSIX.1-2001, POSIX.1-2008 */
3214 /* ntohl: POSIX.1-2001, POSIX.1-2008 */
3221 /* htons: POSIX.1-2001, POSIX.1-2008 */
3228 /* ntohs: POSIX.1-2001, POSIX.1-2008 */