1 /* net.cc: network-related routines.
3 Copyright 1996, 1997, 1998, 1999, 2000, 2001, 2002 Red Hat, Inc.
5 This file is part of Cygwin.
7 This software is a copyrighted work licensed under the terms of the
8 Cygwin license. Please consult the file "CYGWIN_LICENSE" for
11 /* #define DEBUG_NEST_ON 1 */
13 #define __INSIDE_CYGWIN_NET__
17 #include <sys/socket.h>
25 #define USE_SYS_TYPES_FD_SET
37 #include "wsock_event.h"
43 int __stdcall rcmd (char **ahost, unsigned short inport, char *locuser,
44 char *remuser, char *cmd, SOCKET *fd2p);
45 int __stdcall rexec (char **ahost, unsigned short inport, char *locuser,
46 char *password, char *cmd, SOCKET *fd2p);
47 int __stdcall rresvport (int *);
48 int sscanf (const char *, const char *, ...);
49 } /* End of "C" section */
52 wsock_event::prepare ()
54 LPWSAOVERLAPPED ret = NULL;
57 if ((event = WSACreateEvent ()) != WSA_INVALID_EVENT)
59 memset (&ovr, 0, sizeof ovr);
63 else if (GetLastError () == ERROR_PROC_NOT_FOUND) /* winsock2 not available */
66 debug_printf ("%d = wsock_event::prepare ()", ret);
71 wsock_event::wait (int socket, LPDWORD flags)
74 WSAEVENT ev[2] = { event, signal_arrived };
76 switch (WSAWaitForMultipleEvents(2, ev, FALSE, WSA_INFINITE, FALSE))
78 case WSA_WAIT_EVENT_0:
80 if (WSAGetOverlappedResult(socket, &ovr, &len, FALSE, flags))
83 case WSA_WAIT_EVENT_0 + 1:
84 if (!CancelIo ((HANDLE)socket))
86 debug_printf ("CancelIo() %E, fallback to blocking io");
87 WSAGetOverlappedResult(socket, &ovr, &len, TRUE, flags);
90 WSASetLastError (WSAEINTR);
94 default: /* Should be impossible. *LOL* */
95 WSASetLastError (WSAEFAULT);
98 WSACloseEvent (event);
105 /* Cygwin internal */
106 static fhandler_socket *
109 cygheap_fdget cfd (fd);
113 return cfd->is_socket ();
116 /* Cygwin internal */
117 static SOCKET __stdcall
118 set_socket_inheritance (SOCKET sock)
121 if (!DuplicateHandle (hMainProc, (HANDLE) sock, hMainProc, (HANDLE *) &sock,
122 0, TRUE, DUPLICATE_SAME_ACCESS | DUPLICATE_CLOSE_SOURCE))
123 system_printf ("DuplicateHandle failed %E");
125 debug_printf ("DuplicateHandle succeeded osock %p, sock %p", osock, sock);
129 /* htonl: standards? */
130 extern "C" unsigned long int
131 htonl (unsigned long int x)
133 return ((((x & 0x000000ffU) << 24) |
134 ((x & 0x0000ff00U) << 8) |
135 ((x & 0x00ff0000U) >> 8) |
136 ((x & 0xff000000U) >> 24)));
139 /* ntohl: standards? */
140 extern "C" unsigned long int
141 ntohl (unsigned long int x)
146 /* htons: standards? */
147 extern "C" unsigned short
148 htons (unsigned short x)
150 return ((((x & 0x000000ffU) << 8) |
151 ((x & 0x0000ff00U) >> 8)));
154 /* ntohs: standards? */
155 extern "C" unsigned short
156 ntohs (unsigned short x)
161 /* Cygwin internal */
163 dump_protoent (struct protoent *p)
166 debug_printf ("protoent %s %x %x", p->p_name, p->p_aliases, p->p_proto);
169 /* exported as inet_ntoa: BSD 4.3 */
171 cygwin_inet_ntoa (struct in_addr in)
174 #define ntoa_buf _reent_winsup ()->_ntoa_buf
176 static char *ntoa_buf = NULL;
179 char *res = inet_ntoa (in);
186 ntoa_buf = strdup (res);
190 /* exported as inet_addr: BSD 4.3 */
191 extern "C" unsigned long
192 cygwin_inet_addr (const char *cp)
194 if (check_null_str_errno (cp))
196 unsigned long res = inet_addr (cp);
200 /* exported as inet_aton: BSD 4.3
201 inet_aton is not exported by wsock32 and ws2_32,
202 so it has to be implemented here. */
204 cygwin_inet_aton (const char *cp, struct in_addr *inp)
206 if (check_null_str_errno (cp) || check_null_invalid_struct_errno (inp))
209 unsigned long res = inet_addr (cp);
210 if (res == INADDR_NONE && strcmp (cp, "255.255.255.255"))
217 /* undocumented in wsock32.dll */
218 extern "C" unsigned int WINAPI inet_network (const char *);
220 extern "C" unsigned int
221 cygwin_inet_network (const char *cp)
223 if (check_null_str_errno (cp))
225 unsigned int res = inet_network (cp);
229 /* inet_netof is in the standard BSD sockets library. It is useless
230 for modern networks, since it assumes network values which are no
231 longer meaningful, but some existing code calls it. */
233 extern "C" unsigned long
234 inet_netof (struct in_addr in)
236 unsigned long i, res;
238 i = ntohl (in.s_addr);
240 res = (i & IN_CLASSA_NET) >> IN_CLASSA_NSHIFT;
241 else if (IN_CLASSB (i))
242 res = (i & IN_CLASSB_NET) >> IN_CLASSB_NSHIFT;
244 res = (i & IN_CLASSC_NET) >> IN_CLASSC_NSHIFT;
250 /* inet_makeaddr is in the standard BSD sockets library. It is
251 useless for modern networks, since it assumes network values which
252 are no longer meaningful, but some existing code calls it. */
254 extern "C" struct in_addr
255 inet_makeaddr (int net, int lna)
260 if (net < IN_CLASSA_MAX)
261 i = (net << IN_CLASSA_NSHIFT) | (lna & IN_CLASSA_HOST);
262 else if (net < IN_CLASSB_MAX)
263 i = (net << IN_CLASSB_NSHIFT) | (lna & IN_CLASSB_HOST);
264 else if (net < 0x1000000)
265 i = (net << IN_CLASSC_NSHIFT) | (lna & IN_CLASSC_HOST);
269 in.s_addr = htonl (i);
282 static NO_COPY struct tl errmap[] =
284 {WSAEINTR, "WSAEINTR", EINTR},
285 {WSAEWOULDBLOCK, "WSAEWOULDBLOCK", EWOULDBLOCK},
286 {WSAEINPROGRESS, "WSAEINPROGRESS", EINPROGRESS},
287 {WSAEALREADY, "WSAEALREADY", EALREADY},
288 {WSAENOTSOCK, "WSAENOTSOCK", ENOTSOCK},
289 {WSAEDESTADDRREQ, "WSAEDESTADDRREQ", EDESTADDRREQ},
290 {WSAEMSGSIZE, "WSAEMSGSIZE", EMSGSIZE},
291 {WSAEPROTOTYPE, "WSAEPROTOTYPE", EPROTOTYPE},
292 {WSAENOPROTOOPT, "WSAENOPROTOOPT", ENOPROTOOPT},
293 {WSAEPROTONOSUPPORT, "WSAEPROTONOSUPPORT", EPROTONOSUPPORT},
294 {WSAESOCKTNOSUPPORT, "WSAESOCKTNOSUPPORT", ESOCKTNOSUPPORT},
295 {WSAEOPNOTSUPP, "WSAEOPNOTSUPP", EOPNOTSUPP},
296 {WSAEPFNOSUPPORT, "WSAEPFNOSUPPORT", EPFNOSUPPORT},
297 {WSAEAFNOSUPPORT, "WSAEAFNOSUPPORT", EAFNOSUPPORT},
298 {WSAEADDRINUSE, "WSAEADDRINUSE", EADDRINUSE},
299 {WSAEADDRNOTAVAIL, "WSAEADDRNOTAVAIL", EADDRNOTAVAIL},
300 {WSAENETDOWN, "WSAENETDOWN", ENETDOWN},
301 {WSAENETUNREACH, "WSAENETUNREACH", ENETUNREACH},
302 {WSAENETRESET, "WSAENETRESET", ENETRESET},
303 {WSAECONNABORTED, "WSAECONNABORTED", ECONNABORTED},
304 {WSAECONNRESET, "WSAECONNRESET", ECONNRESET},
305 {WSAENOBUFS, "WSAENOBUFS", ENOBUFS},
306 {WSAEISCONN, "WSAEISCONN", EISCONN},
307 {WSAENOTCONN, "WSAENOTCONN", ENOTCONN},
308 {WSAESHUTDOWN, "WSAESHUTDOWN", ESHUTDOWN},
309 {WSAETOOMANYREFS, "WSAETOOMANYREFS", ETOOMANYREFS},
310 {WSAETIMEDOUT, "WSAETIMEDOUT", ETIMEDOUT},
311 {WSAECONNREFUSED, "WSAECONNREFUSED", ECONNREFUSED},
312 {WSAELOOP, "WSAELOOP", ELOOP},
313 {WSAENAMETOOLONG, "WSAENAMETOOLONG", ENAMETOOLONG},
314 {WSAEHOSTDOWN, "WSAEHOSTDOWN", EHOSTDOWN},
315 {WSAEHOSTUNREACH, "WSAEHOSTUNREACH", EHOSTUNREACH},
316 {WSAENOTEMPTY, "WSAENOTEMPTY", ENOTEMPTY},
317 {WSAEPROCLIM, "WSAEPROCLIM", EPROCLIM},
318 {WSAEUSERS, "WSAEUSERS", EUSERS},
319 {WSAEDQUOT, "WSAEDQUOT", EDQUOT},
320 {WSAESTALE, "WSAESTALE", ESTALE},
321 {WSAEREMOTE, "WSAEREMOTE", EREMOTE},
322 {WSAEINVAL, "WSAEINVAL", EINVAL},
323 {WSAEFAULT, "WSAEFAULT", EFAULT},
329 find_winsock_errno (int why)
331 for (int i = 0; errmap[i].s != NULL; ++i)
332 if (why == errmap[i].w)
338 /* Cygwin internal */
340 __set_winsock_errno (const char *fn, int ln)
342 DWORD werr = WSAGetLastError ();
343 int err = find_winsock_errno (werr);
345 syscall_printf ("%s:%d - winsock error %d -> errno %d", fn, ln, werr, err);
349 * Since the member `s' isn't used for debug output we can use it
350 * for the error text returned by herror and hstrerror.
352 static NO_COPY struct tl host_errmap[] =
354 {WSAHOST_NOT_FOUND, "Unknown host", HOST_NOT_FOUND},
355 {WSATRY_AGAIN, "Host name lookup failure", TRY_AGAIN},
356 {WSANO_RECOVERY, "Unknown server error", NO_RECOVERY},
357 {WSANO_DATA, "No address associated with name", NO_DATA},
361 /* Cygwin internal */
367 int why = WSAGetLastError ();
368 for (i = 0; host_errmap[i].w != 0; ++i)
369 if (why == host_errmap[i].w)
372 if (host_errmap[i].w != 0)
373 h_errno = host_errmap[i].e;
375 h_errno = NETDB_INTERNAL;
379 free_char_list (char **clist)
383 for (char **cl = clist; *cl; ++cl)
390 dup_char_list (char **src)
395 for (char **cl = src; *cl; ++cl)
397 if (!(dst = (char **) calloc (cnt + 1, sizeof *dst)))
400 if (!(dst[cnt] = strdup (src[cnt])))
405 #define free_addr_list(addr_list) free_char_list (addr_list)
408 dup_addr_list (char **src, unsigned int size)
413 for (char **cl = src; *cl; ++cl)
415 if (!(dst = (char **) calloc (cnt + 1, sizeof *dst)))
419 if (!(dst[cnt] = (char *) malloc(size)))
421 memcpy(dst[cnt], src[cnt], size);
427 free_protoent_ptr (struct protoent *&p)
431 debug_printf ("protoent: %s", p->p_name);
435 free_char_list (p->p_aliases);
440 static struct protoent *
441 dup_protoent_ptr (struct protoent *src)
446 struct protoent *dst = (struct protoent *) calloc (1, sizeof *dst);
450 debug_printf ("protoent: %s", src->p_name);
452 dst->p_proto = src->p_proto;
453 if (src->p_name && !(dst->p_name = strdup (src->p_name)))
455 if (src->p_aliases && !(dst->p_aliases = dup_char_list (src->p_aliases)))
458 debug_printf ("protoent: copied %s", dst->p_name);
463 free_protoent_ptr (dst);
468 #define protoent_buf _reent_winsup ()->_protoent_buf
470 static struct protoent *protoent_buf = NULL;
473 /* exported as getprotobyname: standards? */
474 extern "C" struct protoent *
475 cygwin_getprotobyname (const char *p)
477 if (check_null_str_errno (p))
479 free_protoent_ptr (protoent_buf);
480 protoent_buf = dup_protoent_ptr (getprotobyname (p));
482 set_winsock_errno ();
484 dump_protoent (protoent_buf);
488 /* exported as getprotobynumber: standards? */
489 extern "C" struct protoent *
490 cygwin_getprotobynumber (int number)
492 free_protoent_ptr (protoent_buf);
493 protoent_buf = dup_protoent_ptr (getprotobynumber (number));
495 set_winsock_errno ();
497 dump_protoent (protoent_buf);
502 fdsock (int& fd, const char *name, SOCKET soc)
504 if (!winsock2_active)
505 soc = set_socket_inheritance (soc);
507 debug_printf ("not setting socket inheritance since winsock2_active %d", winsock2_active);
508 fhandler_socket *fh = (fhandler_socket *) cygheap->fdtab.build_fhandler (fd, FH_SOCKET, name);
509 fh->set_io_handle ((HANDLE) soc);
510 fh->set_flags (O_RDWR);
511 debug_printf ("fd %d, name '%s', soc %p", fd, name, soc);
515 /* exported as socket: standards? */
517 cygwin_socket (int af, int type, int protocol)
526 debug_printf ("socket (%d, %d, %d)", af, type, protocol);
528 soc = socket (AF_INET, type, af == AF_LOCAL ? 0 : protocol);
530 if (soc == INVALID_SOCKET)
532 set_winsock_errno ();
538 name = (type == SOCK_STREAM ? "/dev/tcp" : "/dev/udp");
540 name = (type == SOCK_STREAM ? "/dev/streamsocket" : "/dev/dgsocket");
542 fdsock (fd, name, soc)->set_addr_family (af);
547 syscall_printf ("%d = socket (%d, %d, %d)", res, af, type, protocol);
551 /* cygwin internal: map sockaddr into internet domain address */
553 static int get_inet_addr (const struct sockaddr *in, int inlen,
554 struct sockaddr_in *out, int *outlen, int* secret = 0)
557 int* secret_ptr = (secret ? : secret_buf);
559 if (in->sa_family == AF_INET)
561 *out = * (sockaddr_in *)in;
565 else if (in->sa_family == AF_LOCAL)
567 int fd = _open (in->sa_data, O_RDONLY);
573 memset (buf, 0, sizeof buf);
574 if (read (fd, buf, sizeof buf) != -1)
577 sin.sin_family = AF_INET;
578 sscanf (buf + strlen (SOCKET_COOKIE), "%hu %08x-%08x-%08x-%08x",
580 secret_ptr, secret_ptr + 1, secret_ptr + 2, secret_ptr + 3);
581 sin.sin_port = htons (sin.sin_port);
582 sin.sin_addr.s_addr = htonl (INADDR_LOOPBACK);
584 *outlen = sizeof sin;
592 set_errno (EAFNOSUPPORT);
597 /* exported as sendto: standards? */
599 cygwin_sendto (int fd,
603 const struct sockaddr *to,
607 wsock_event wsock_evt;
609 fhandler_socket *h = get (fd);
611 if ((len && __check_invalid_read_ptr_errno (buf, (unsigned) len))
612 || __check_null_invalid_struct_errno (to, tolen)
618 sigframe thisframe (mainthread);
620 if (get_inet_addr (to, tolen, &sin, &tolen) == 0)
623 if (h->is_nonblocking () || !(ovr = wsock_evt.prepare ()))
625 debug_printf ("Fallback to winsock 1 sendto call");
626 if ((res = sendto (h->get_socket (), (const char *) buf, len, flags,
627 (sockaddr *) &sin, tolen)) == SOCKET_ERROR)
629 set_winsock_errno ();
635 WSABUF wsabuf = { len, (char *) buf };
637 if (WSASendTo (h->get_socket (), &wsabuf, 1, &ret, (DWORD)flags,
638 (sockaddr *) &sin, tolen, ovr, NULL) != SOCKET_ERROR)
640 else if ((res = WSAGetLastError ()) != WSA_IO_PENDING)
642 set_winsock_errno ();
645 else if ((res = wsock_evt.wait (h->get_socket (), (DWORD *)&flags)) == -1)
646 set_winsock_errno ();
650 syscall_printf ("%d = sendto (%d, %x, %x, %x)", res, fd, buf, len, flags);
655 /* exported as recvfrom: standards? */
657 cygwin_recvfrom (int fd,
661 struct sockaddr *from,
665 wsock_event wsock_evt;
667 fhandler_socket *h = get (fd);
669 if (__check_null_invalid_struct_errno (buf, (unsigned) len)
670 || check_null_invalid_struct_errno (fromlen)
671 || (from && __check_null_invalid_struct_errno (from, (unsigned) *fromlen))
676 sigframe thisframe (mainthread);
678 if (h->is_nonblocking () ||!(ovr = wsock_evt.prepare ()))
680 debug_printf ("Fallback to winsock 1 recvfrom call");
681 if ((res = recvfrom (h->get_socket (), buf, len, flags, from, fromlen))
684 set_winsock_errno ();
690 WSABUF wsabuf = { len, (char *) buf };
692 if (WSARecvFrom (h->get_socket (), &wsabuf, 1, &ret, (DWORD *)&flags,
693 from, fromlen, ovr, NULL) != SOCKET_ERROR)
695 else if ((res = WSAGetLastError ()) != WSA_IO_PENDING)
697 set_winsock_errno ();
700 else if ((res = wsock_evt.wait (h->get_socket (), (DWORD *)&flags)) == -1)
701 set_winsock_errno ();
705 syscall_printf ("%d = recvfrom (%d, %x, %x, %x)", res, fd, buf, len, flags);
710 /* exported as setsockopt: standards? */
712 cygwin_setsockopt (int fd,
718 fhandler_socket *h = get (fd);
720 const char *name = "error";
722 if ((!optval || !__check_invalid_read_ptr_errno (optval, optlen)) && h)
724 /* For the following debug_printf */
731 name="SO_ACCEPTCONN";
746 name="SO_USELOOPBACK";
759 res = setsockopt (h->get_socket (), level, optname,
760 (const char *) optval, optlen);
763 syscall_printf ("setsockopt optval=%x", *(long *) optval);
766 set_winsock_errno ();
769 syscall_printf ("%d = setsockopt (%d, %d, %x (%s), %x, %d)",
770 res, fd, level, optname, name, optval, optlen);
774 /* exported as getsockopt: standards? */
776 cygwin_getsockopt (int fd,
782 fhandler_socket *h = get (fd);
784 const char *name = "error";
785 if (!check_null_invalid_struct_errno (optlen)
786 && (!optval || !__check_null_invalid_struct_errno (optval, (unsigned) *optlen))
789 /* For the following debug_printf */
796 name="SO_ACCEPTCONN";
811 name="SO_USELOOPBACK";
824 res = getsockopt (h->get_socket (), level, optname,
825 (char *) optval, (int *) optlen);
827 if (optname == SO_ERROR)
829 int *e = (int *) optval;
830 *e = find_winsock_errno (*e);
834 set_winsock_errno ();
837 syscall_printf ("%d = getsockopt (%d, %d, %x (%s), %x, %d)",
838 res, fd, level, optname, name, optval, optlen);
842 /* exported as connect: standards? */
844 cygwin_connect (int fd,
845 const struct sockaddr *name,
849 BOOL secret_check_failed = FALSE;
850 BOOL in_progress = FALSE;
851 fhandler_socket *sock = get (fd);
854 sigframe thisframe (mainthread);
856 if (__check_invalid_read_ptr_errno (name, namelen))
859 if (get_inet_addr (name, namelen, &sin, &namelen, secret) == 0)
866 res = connect (sock->get_socket (), (sockaddr *) &sin, namelen);
869 /* Special handling for connect to return the correct error code
870 when called on a non-blocking socket. */
871 if (sock->is_nonblocking ())
873 DWORD err = WSAGetLastError ();
874 if (err == WSAEWOULDBLOCK || err == WSAEALREADY)
876 WSASetLastError (WSAEINPROGRESS);
879 else if (err == WSAEINVAL)
880 WSASetLastError (WSAEISCONN);
882 set_winsock_errno ();
884 if (sock->get_addr_family () == AF_LOCAL)
886 if (!res || in_progress)
888 if (!sock->create_secret_event (secret))
890 secret_check_failed = TRUE;
892 else if (in_progress)
893 sock->signal_secret_event ();
896 if (!secret_check_failed && !res)
898 if (!sock->check_peer_secret_event (&sin, secret))
900 debug_printf ( "accept from unauthorized server" );
901 secret_check_failed = TRUE;
905 if (secret_check_failed)
907 sock->close_secret_event ();
910 set_errno (ECONNREFUSED);
919 free_servent_ptr (struct servent *&p)
923 debug_printf ("servent: %s", p->s_name);
929 free_char_list (p->s_aliases);
943 static struct servent *
944 dup_servent_ptr (struct servent *src)
949 struct servent *dst = (struct servent *) calloc (1, sizeof *dst);
953 debug_printf ("servent: %s", src->s_name);
955 dst->s_port = src->s_port;
956 if (src->s_name && !(dst->s_name = strdup (src->s_name)))
958 if (src->s_aliases && !(dst->s_aliases = dup_char_list (src->s_aliases)))
961 if (IsBadReadPtr (src->s_proto, sizeof (src->s_proto))
962 && !IsBadReadPtr (((pservent *) src)->s_proto, sizeof (src->s_proto)))
963 s_proto = ((pservent *)src)->s_proto;
965 s_proto = src->s_proto;
967 if (s_proto && !(dst->s_proto = strdup (s_proto)))
970 debug_printf ("servent: copied %s", dst->s_name);
975 free_servent_ptr (dst);
980 #define servent_buf _reent_winsup ()->_servent_buf
982 static struct servent *servent_buf = NULL;
985 /* exported as getservbyname: standards? */
986 extern "C" struct servent *
987 cygwin_getservbyname (const char *name, const char *proto)
989 if (check_null_str_errno (name)
990 || (proto != NULL && check_null_str_errno (proto)))
993 free_servent_ptr (servent_buf);
994 servent_buf = dup_servent_ptr (getservbyname (name, proto));
996 set_winsock_errno ();
998 syscall_printf ("%x = getservbyname (%s, %s)", servent_buf, name, proto);
1002 /* exported as getservbyport: standards? */
1003 extern "C" struct servent *
1004 cygwin_getservbyport (int port, const char *proto)
1006 if (proto != NULL && check_null_str_errno (proto))
1009 free_servent_ptr (servent_buf);
1010 servent_buf = dup_servent_ptr (getservbyport (port, proto));
1012 set_winsock_errno ();
1014 syscall_printf ("%x = getservbyport (%d, %s)", servent_buf, port, proto);
1019 cygwin_gethostname (char *name, size_t len)
1021 int PASCAL win32_gethostname (char*, int);
1023 if (__check_null_invalid_struct_errno (name, len))
1026 if (wsock32_handle == NULL ||
1027 win32_gethostname (name, len) == SOCKET_ERROR)
1029 DWORD local_len = len;
1031 if (!GetComputerNameA (name, &local_len))
1033 set_winsock_errno ();
1037 debug_printf ("name %s\n", name);
1043 free_hostent_ptr (struct hostent *&p)
1047 debug_printf ("hostent: %s", p->h_name);
1050 free ((void *)p->h_name);
1051 free_char_list (p->h_aliases);
1052 free_addr_list (p->h_addr_list);
1057 static struct hostent *
1058 dup_hostent_ptr (struct hostent *src)
1063 struct hostent *dst = (struct hostent *) calloc (1, sizeof *dst);
1067 debug_printf ("hostent: %s", src->h_name);
1069 dst->h_addrtype = src->h_addrtype;
1070 dst->h_length = src->h_length;
1071 if (src->h_name && !(dst->h_name = strdup (src->h_name)))
1073 if (src->h_aliases && !(dst->h_aliases = dup_char_list (src->h_aliases)))
1075 if (src->h_addr_list
1076 && !(dst->h_addr_list = dup_addr_list(src->h_addr_list, src->h_length)))
1079 debug_printf ("hostent: copied %s", dst->h_name);
1084 free_hostent_ptr (dst);
1089 #define hostent_buf _reent_winsup ()->_hostent_buf
1091 static struct hostent *hostent_buf = NULL;
1094 /* exported as gethostbyname: standards? */
1095 extern "C" struct hostent *
1096 cygwin_gethostbyname (const char *name)
1098 static unsigned char tmp_addr[4];
1099 static struct hostent tmp;
1100 static char *tmp_aliases[1];
1101 static char *tmp_addr_list[2];
1102 static int a, b, c, d;
1104 if (check_null_str_errno (name))
1107 if (sscanf (name, "%d.%d.%d.%d", &a, &b, &c, &d) == 4)
1109 /* In case you don't have DNS, at least x.x.x.x still works */
1110 memset (&tmp, 0, sizeof (tmp));
1115 tmp_addr_list[0] = (char *)tmp_addr;
1117 tmp.h_aliases = tmp_aliases;
1120 tmp.h_addr_list = tmp_addr_list;
1124 free_hostent_ptr (hostent_buf);
1125 hostent_buf = dup_hostent_ptr (gethostbyname (name));
1128 set_winsock_errno ();
1133 debug_printf ("h_name %s", hostent_buf->h_name);
1139 /* exported as gethostbyaddr: standards? */
1140 extern "C" struct hostent *
1141 cygwin_gethostbyaddr (const char *addr, int len, int type)
1143 if (__check_null_invalid_struct_errno (addr, len))
1146 free_hostent_ptr (hostent_buf);
1147 hostent_buf = dup_hostent_ptr (gethostbyaddr (addr, len, type));
1150 set_winsock_errno ();
1155 debug_printf ("h_name %s", hostent_buf->h_name);
1161 /* exported as accept: standards? */
1163 cygwin_accept (int fd, struct sockaddr *peer, int *len)
1166 && (check_null_invalid_struct_errno (len)
1167 || __check_null_invalid_struct_errno (peer, (unsigned) *len)))
1171 BOOL secret_check_failed = FALSE;
1172 BOOL in_progress = FALSE;
1173 sigframe thisframe (mainthread);
1175 fhandler_socket *sock = get (fd);
1178 /* Allows NULL peer and len parameters. */
1179 struct sockaddr_in peer_dummy;
1182 peer = (struct sockaddr *) &peer_dummy;
1185 len_dummy = sizeof (struct sockaddr_in);
1189 /* accept on NT fails if len < sizeof (sockaddr_in)
1190 * some programs set len to
1191 * sizeof (name.sun_family) + strlen (name.sun_path) for UNIX domain
1193 if (len && ((unsigned) *len < sizeof (struct sockaddr_in)))
1194 *len = sizeof (struct sockaddr_in);
1196 res = accept (sock->get_socket (), peer, len); // can't use a blocking call inside a lock
1198 if ((SOCKET) res == (SOCKET) INVALID_SOCKET &&
1199 WSAGetLastError () == WSAEWOULDBLOCK)
1202 if (sock->get_addr_family () == AF_LOCAL)
1204 if ((SOCKET) res != (SOCKET) INVALID_SOCKET || in_progress)
1206 if (!sock->create_secret_event ())
1207 secret_check_failed = TRUE;
1208 else if (in_progress)
1209 sock->signal_secret_event ();
1212 if (!secret_check_failed &&
1213 (SOCKET) res != (SOCKET) INVALID_SOCKET)
1215 if (!sock->check_peer_secret_event ((struct sockaddr_in*) peer))
1217 debug_printf ("connect from unauthorized client");
1218 secret_check_failed = TRUE;
1222 if (secret_check_failed)
1224 sock->close_secret_event ();
1225 if ((SOCKET) res != (SOCKET) INVALID_SOCKET)
1227 set_errno (ECONNABORTED);
1234 cygheap_fdnew res_fd;
1236 /* FIXME: what is correct errno? */;
1237 else if ((SOCKET) res == (SOCKET) INVALID_SOCKET)
1238 set_winsock_errno ();
1241 fhandler_socket* res_fh = fdsock (res_fd, sock->get_name (), res);
1242 if (sock->get_addr_family () == AF_LOCAL)
1243 res_fh->set_sun_path (sock->get_sun_path ());
1244 res_fh->set_addr_family (sock->get_addr_family ());
1249 syscall_printf ("%d = accept (%d, %x, %x)", res, fd, peer, len);
1253 /* exported as bind: standards? */
1255 cygwin_bind (int fd, const struct sockaddr *my_addr, int addrlen)
1257 if (__check_null_invalid_struct_errno (my_addr, addrlen))
1262 fhandler_socket *sock = get (fd);
1265 if (my_addr->sa_family == AF_LOCAL)
1267 #define un_addr ((struct sockaddr_un *) my_addr)
1268 struct sockaddr_in sin;
1269 int len = sizeof sin;
1272 if (strlen (un_addr->sun_path) >= UNIX_PATH_LEN)
1274 set_errno (ENAMETOOLONG);
1277 sin.sin_family = AF_INET;
1279 sin.sin_addr.s_addr = htonl (INADDR_LOOPBACK);
1280 if (bind (sock->get_socket (), (sockaddr *) &sin, len))
1282 syscall_printf ("AF_LOCAL: bind failed %d", get_errno ());
1283 set_winsock_errno ();
1286 if (getsockname (sock->get_socket (), (sockaddr *) &sin, &len))
1288 syscall_printf ("AF_LOCAL: getsockname failed %d", get_errno ());
1289 set_winsock_errno ();
1293 sin.sin_port = ntohs (sin.sin_port);
1294 debug_printf ("AF_LOCAL: socket bound to port %u", sin.sin_port);
1296 /* bind must fail if file system socket object already exists
1297 so _open () is called with O_EXCL flag. */
1298 fd = _open (un_addr->sun_path,
1299 O_WRONLY | O_CREAT | O_EXCL | O_BINARY,
1303 if (get_errno () == EEXIST)
1304 set_errno (EADDRINUSE);
1308 sock->set_connect_secret ();
1310 char buf[sizeof (SOCKET_COOKIE) + 80];
1311 __small_sprintf (buf, "%s%u ", SOCKET_COOKIE, sin.sin_port);
1312 sock->get_connect_secret (strchr (buf, '\0'));
1313 len = strlen (buf) + 1;
1315 /* Note that the terminating nul is written. */
1316 if (_write (fd, buf, len) != len)
1320 _unlink (un_addr->sun_path);
1325 chmod (un_addr->sun_path,
1326 (S_IFSOCK | S_IRWXU | S_IRWXG | S_IRWXO) & ~cygheap->umask);
1327 sock->set_sun_path (un_addr->sun_path);
1332 else if (bind (sock->get_socket (), my_addr, addrlen))
1333 set_winsock_errno ();
1339 syscall_printf ("%d = bind (%d, %x, %d)", res, fd, my_addr, addrlen);
1343 /* exported as getsockname: standards? */
1345 cygwin_getsockname (int fd, struct sockaddr *addr, int *namelen)
1347 if (check_null_invalid_struct_errno (namelen)
1348 || __check_null_invalid_struct_errno (addr, (unsigned) *namelen))
1353 fhandler_socket *sock = get (fd);
1356 if (sock->get_addr_family () == AF_LOCAL)
1358 struct sockaddr_un *sun = (struct sockaddr_un *) addr;
1359 memset (sun, 0, *namelen);
1360 sun->sun_family = AF_LOCAL;
1362 if (!sock->get_sun_path ())
1363 sun->sun_path[0] = '\0';
1365 /* According to SUSv2 "If the actual length of the address is
1366 greater than the length of the supplied sockaddr structure, the
1367 stored address will be truncated." We play it save here so
1368 that the path always has a trailing 0 even if it's truncated. */
1369 strncpy (sun->sun_path, sock->get_sun_path (),
1370 *namelen - sizeof *sun + sizeof sun->sun_path - 1);
1372 *namelen = sizeof *sun - sizeof sun->sun_path
1373 + strlen (sun->sun_path) + 1;
1378 res = getsockname (sock->get_socket (), addr, namelen);
1380 set_winsock_errno ();
1383 syscall_printf ("%d = getsockname (%d, %x, %d)", res, fd, addr, namelen);
1387 /* exported as listen: standards? */
1389 cygwin_listen (int fd, int backlog)
1394 fhandler_socket *sock = get (fd);
1397 res = listen (sock->get_socket (), backlog);
1399 set_winsock_errno ();
1401 syscall_printf ("%d = listen (%d, %d)", res, fd, backlog);
1405 /* exported as shutdown: standards? */
1407 cygwin_shutdown (int fd, int how)
1410 sigframe thisframe (mainthread);
1412 fhandler_socket *sock = get (fd);
1415 res = shutdown (sock->get_socket (), how);
1417 set_winsock_errno ();
1422 sock->set_shutdown_read ();
1425 sock->set_shutdown_write ();
1428 sock->set_shutdown_read ();
1429 sock->set_shutdown_write ();
1433 syscall_printf ("%d = shutdown (%d, %d)", res, fd, how);
1437 /* exported as hstrerror: BSD 4.3 */
1438 extern "C" const char *
1439 cygwin_hstrerror (int err)
1443 for (i = 0; host_errmap[i].e != 0; ++i)
1444 if (err == host_errmap[i].e)
1447 return host_errmap[i].s;
1450 /* exported as herror: BSD 4.3 */
1452 cygwin_herror (const char *s)
1454 if (s && check_null_str (s))
1456 if (cygheap->fdtab.not_open (2))
1461 write (2, s, strlen (s));
1465 const char *h_errstr = cygwin_hstrerror (h_errno);
1470 case NETDB_INTERNAL:
1471 h_errstr = "Resolver internal error";
1474 h_errstr = "Resolver error 0 (no error)";
1477 h_errstr = "Unknown resolver error";
1480 write (2, h_errstr, strlen (h_errstr));
1484 /* exported as getpeername: standards? */
1486 cygwin_getpeername (int fd, struct sockaddr *name, int *len)
1489 if (check_null_invalid_struct_errno (len)
1490 || __check_null_invalid_struct_errno (name, (unsigned) *len))
1493 fhandler_socket *h = get (fd);
1499 res = getpeername (h->get_socket (), name, len);
1501 set_winsock_errno ();
1504 debug_printf ("%d = getpeername %d", res, h->get_socket ());
1508 /* exported as recv: standards? */
1510 cygwin_recv (int fd, void *buf, int len, unsigned int flags)
1513 fhandler_socket *fh = get (fd);
1515 if (__check_null_invalid_struct_errno (buf, len) || !fh)
1518 res = fh->recv (buf, len, flags);
1520 syscall_printf ("%d = recv (%d, %x, %x, %x)", res, fd, buf, len, flags);
1525 /* exported as send: standards? */
1527 cygwin_send (int fd, const void *buf, int len, unsigned int flags)
1530 fhandler_socket *fh = get (fd);
1532 if (__check_invalid_read_ptr_errno (buf, len) || !fh)
1535 res = fh->send (buf, len, flags);
1537 syscall_printf ("%d = send (%d, %x, %d, %x)", res, fd, buf, len, flags);
1542 /* getdomainname: standards? */
1544 getdomainname (char *domain, int len)
1547 * This works for Win95 only if the machine is configured to use MS-TCP.
1548 * If a third-party TCP is being used this will fail.
1549 * FIXME: On Win95, is there a way to portably check the TCP stack
1550 * in use and include paths for the Domain name in each ?
1551 * Punt for now and assume MS-TCP on Win95.
1553 if (__check_null_invalid_struct_errno (domain, len))
1556 reg_key r (HKEY_LOCAL_MACHINE, KEY_READ,
1557 (!wincap.is_winnt ()) ? "System" : "SYSTEM",
1558 "CurrentControlSet", "Services",
1559 (!wincap.is_winnt ()) ? "VxD" : "Tcpip",
1560 (!wincap.is_winnt ()) ? "MSTCP" : "Parameters",
1563 /* FIXME: Are registry keys case sensitive? */
1564 if (r.error () || r.get_string ("Domain", domain, len, "") != ERROR_SUCCESS)
1573 /* Cygwin internal */
1574 /* Fill out an ifconf struct. */
1577 * IFCONF 98/ME, NTSP4, W2K:
1578 * Use IP Helper Library
1581 get_2k_ifconf (struct ifconf *ifc, int what)
1584 char eth[2] = "/", ppp[2] = "/", slp[2] = "/", sub[2] = "0", tok[2] = "/";
1586 /* Union maps buffer to correct struct */
1587 struct ifreq *ifr = ifc->ifc_req;
1589 DWORD if_cnt, ip_cnt, lip, lnp;
1590 DWORD siz_if_table = 0;
1591 DWORD siz_ip_table = 0;
1593 PMIB_IPADDRTABLE ipt;
1594 struct sockaddr_in *sa = NULL;
1595 struct sockaddr *so = NULL;
1597 if (GetIfTable(NULL, &siz_if_table, TRUE) == ERROR_INSUFFICIENT_BUFFER &&
1598 GetIpAddrTable(NULL, &siz_ip_table, TRUE) == ERROR_INSUFFICIENT_BUFFER &&
1599 (ift = (PMIB_IFTABLE) alloca (siz_if_table)) &&
1600 (ipt = (PMIB_IPADDRTABLE) alloca (siz_ip_table)) &&
1601 !GetIfTable(ift, &siz_if_table, TRUE) &&
1602 !GetIpAddrTable(ipt, &siz_ip_table, TRUE))
1604 /* Iterate over all known interfaces */
1605 for (if_cnt = 0; if_cnt < ift->dwNumEntries; ++if_cnt)
1608 /* Iterate over all configured IP-addresses */
1609 for (ip_cnt = 0; ip_cnt < ipt->dwNumEntries; ++ip_cnt)
1611 /* Does the IP address belong to the interface? */
1612 if (ipt->table[ip_cnt].dwIndex == ift->table[if_cnt].dwIndex)
1614 /* Setup the interface name */
1615 switch (ift->table[if_cnt].dwType)
1617 case MIB_IF_TYPE_TOKENRING:
1619 strcpy (ifr->ifr_name, "tok");
1620 strcat (ifr->ifr_name, tok);
1622 case MIB_IF_TYPE_ETHERNET:
1625 strcpy (ifr->ifr_name, "eth");
1626 strcat (ifr->ifr_name, eth);
1628 case MIB_IF_TYPE_PPP:
1630 strcpy (ifr->ifr_name, "ppp");
1631 strcat (ifr->ifr_name, ppp);
1633 case MIB_IF_TYPE_SLIP:
1635 strcpy (ifr->ifr_name, "slp");
1636 strcat (ifr->ifr_name, slp);
1638 case MIB_IF_TYPE_LOOPBACK:
1639 strcpy (ifr->ifr_name, "lo");
1646 strcat (ifr->ifr_name, ":");
1647 strcat (ifr->ifr_name, sub);
1650 /* setup sockaddr struct */
1655 sa = (struct sockaddr_in *) &ifr->ifr_addr;
1656 sa->sin_addr.s_addr = ipt->table[ip_cnt].dwAddr;
1657 sa->sin_family = AF_INET;
1660 case SIOCGIFBRDADDR:
1661 sa = (struct sockaddr_in *) &ifr->ifr_broadaddr;
1663 /* Unfortunately, the field returns only crap. */
1664 sa->sin_addr.s_addr = ipt->table[ip_cnt].dwBCastAddr;
1666 lip = ipt->table[ip_cnt].dwAddr;
1667 lnp = ipt->table[ip_cnt].dwMask;
1668 sa->sin_addr.s_addr = lip & lnp | ~lnp;
1669 sa->sin_family = AF_INET;
1673 case SIOCGIFNETMASK:
1674 sa = (struct sockaddr_in *) &ifr->ifr_netmask;
1675 sa->sin_addr.s_addr = ipt->table[ip_cnt].dwMask;
1676 sa->sin_family = AF_INET;
1680 so = &ifr->ifr_hwaddr;
1681 for (UINT i = 0; i < IFHWADDRLEN; ++i)
1682 if (i >= ift->table[if_cnt].dwPhysAddrLen)
1683 so->sa_data[i] = '\0';
1685 so->sa_data[i] = ift->table[if_cnt].bPhysAddr[i];
1686 so->sa_family = AF_INET;
1689 ifr->ifr_metric = 1;
1692 ifr->ifr_mtu = ift->table[if_cnt].dwMtu;
1696 if ((caddr_t) ++ifr >
1697 ifc->ifc_buf + ifc->ifc_len - sizeof (struct ifreq))
1704 /* Set the correct length */
1705 ifc->ifc_len = cnt * sizeof (struct ifreq);
1709 * IFCONF Windows NT < SP4:
1710 * Look at the Bind value in
1711 * HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\Tcpip\Linkage\
1712 * This is a REG_MULTI_SZ with strings of the form:
1713 * \Device\<Netcard>, where netcard is the name of the net device.
1715 * HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\<NetCard>\
1717 * at the IPAddress, Subnetmask and DefaultGateway values for the
1721 get_nt_ifconf (struct ifconf *ifc, int what)
1724 unsigned long lip, lnp;
1725 struct sockaddr_in *sa = NULL;
1726 struct sockaddr *so = NULL;
1729 char *binding = (char *) 0;
1731 /* Union maps buffer to correct struct */
1732 struct ifreq *ifr = ifc->ifc_req;
1734 if (RegOpenKeyEx (HKEY_LOCAL_MACHINE,
1736 "CurrentControlSet\\"
1740 0, KEY_READ, &key) == ERROR_SUCCESS)
1742 if (RegQueryValueEx (key, "Bind",
1744 NULL, &size) == ERROR_SUCCESS)
1746 binding = (char *) alloca (size);
1747 if (RegQueryValueEx (key, "Bind",
1749 (unsigned char *) binding,
1750 &size) != ERROR_SUCCESS)
1760 char *bp, eth[2] = "/";
1761 char cardkey[256], ipaddress[256], netmask[256];
1763 for (bp = binding; *bp; bp += strlen (bp) + 1)
1765 bp += strlen ("\\Device\\");
1766 strcpy (cardkey, "SYSTEM\\CurrentControlSet\\Services\\");
1767 strcat (cardkey, bp);
1768 strcat (cardkey, "\\Parameters\\Tcpip");
1770 if (RegOpenKeyEx (HKEY_LOCAL_MACHINE, cardkey,
1771 0, KEY_READ, &key) != ERROR_SUCCESS)
1774 if (RegQueryValueEx (key, "IPAddress",
1776 (unsigned char *) ipaddress,
1777 (size = 256, &size)) == ERROR_SUCCESS
1778 && RegQueryValueEx (key, "SubnetMask",
1780 (unsigned char *) netmask,
1781 (size = 256, &size)) == ERROR_SUCCESS)
1784 char dhcpaddress[256], dhcpnetmask[256];
1786 for (ip = ipaddress, np = netmask;
1788 ip += strlen (ip) + 1, np += strlen (np) + 1)
1790 if ((caddr_t) ++ifr > ifc->ifc_buf
1792 - sizeof (struct ifreq))
1795 if (! strncmp (bp, "NdisWan", 7))
1797 strcpy (ifr->ifr_name, "ppp");
1798 strcat (ifr->ifr_name, bp + 7);
1803 strcpy (ifr->ifr_name, "eth");
1804 strcat (ifr->ifr_name, eth);
1806 memset (&ifr->ifr_addr, '\0', sizeof ifr->ifr_addr);
1807 if (cygwin_inet_addr (ip) == 0L
1808 && RegQueryValueEx (key, "DhcpIPAddress",
1810 (unsigned char *) dhcpaddress,
1811 (size = 256, &size))
1813 && RegQueryValueEx (key, "DhcpSubnetMask",
1815 (unsigned char *) dhcpnetmask,
1816 (size = 256, &size))
1823 sa = (struct sockaddr_in *) &ifr->ifr_addr;
1824 sa->sin_addr.s_addr = cygwin_inet_addr (dhcpaddress);
1825 sa->sin_family = AF_INET;
1828 case SIOCGIFBRDADDR:
1829 lip = cygwin_inet_addr (dhcpaddress);
1830 lnp = cygwin_inet_addr (dhcpnetmask);
1831 sa = (struct sockaddr_in *) &ifr->ifr_broadaddr;
1832 sa->sin_addr.s_addr = lip & lnp | ~lnp;
1833 sa->sin_family = AF_INET;
1836 case SIOCGIFNETMASK:
1837 sa = (struct sockaddr_in *) &ifr->ifr_netmask;
1838 sa->sin_addr.s_addr =
1839 cygwin_inet_addr (dhcpnetmask);
1840 sa->sin_family = AF_INET;
1844 so = &ifr->ifr_hwaddr;
1845 memset (so->sa_data, 0, IFHWADDRLEN);
1846 so->sa_family = AF_INET;
1849 ifr->ifr_metric = 1;
1852 ifr->ifr_mtu = 1500;
1862 sa = (struct sockaddr_in *) &ifr->ifr_addr;
1863 sa->sin_addr.s_addr = cygwin_inet_addr (ip);
1864 sa->sin_family = AF_INET;
1867 case SIOCGIFBRDADDR:
1868 lip = cygwin_inet_addr (ip);
1869 lnp = cygwin_inet_addr (np);
1870 sa = (struct sockaddr_in *) &ifr->ifr_broadaddr;
1871 sa->sin_addr.s_addr = lip & lnp | ~lnp;
1872 sa->sin_family = AF_INET;
1875 case SIOCGIFNETMASK:
1876 sa = (struct sockaddr_in *) &ifr->ifr_netmask;
1877 sa->sin_addr.s_addr = cygwin_inet_addr (np);
1878 sa->sin_family = AF_INET;
1882 so = &ifr->ifr_hwaddr;
1883 memset (so->sa_data, 0, IFHWADDRLEN);
1884 so->sa_family = AF_INET;
1887 ifr->ifr_metric = 1;
1890 ifr->ifr_mtu = 1500;
1901 /* Set the correct length */
1902 ifc->ifc_len = cnt * sizeof (struct ifreq);
1906 * IFCONF Windows 95:
1907 * HKLM/Enum/Network/MSTCP/"*"
1908 * -> Value "Driver" enthält Subkey relativ zu
1909 * HKLM/System/CurrentControlSet/Class/
1910 * -> In Subkey "Bindings" die Values aufzählen
1911 * -> Enthält Subkeys der Form "VREDIR\*"
1912 * Das * ist ein Subkey relativ zu
1913 * HKLM/System/CurrentControlSet/Class/Net/
1914 * HKLM/System/CurrentControlSet/Class/"Driver"
1915 * -> Value "IPAddress"
1917 * HKLM/System/CurrentControlSet/Class/Net/"*"(aus "VREDIR\*")
1918 * -> Wenn Value "AdapterName" == "MS$PPP" -> ppp interface
1919 * -> Value "DriverDesc" enthält den Namen
1923 get_95_ifconf (struct ifconf *ifc, int what)
1926 unsigned long lip, lnp;
1927 struct sockaddr_in *sa = NULL;
1928 struct sockaddr *so = NULL;
1937 /* Union maps buffer to correct struct */
1938 struct ifreq *ifr = ifc->ifc_req;
1940 if (RegOpenKeyEx (HKEY_LOCAL_MACHINE, "Enum\\Network\\MSTCP",
1941 0, KEY_READ, &key) != ERROR_SUCCESS)
1943 /* Set the correct length */
1944 ifc->ifc_len = cnt * sizeof (struct ifreq);
1949 (res = RegEnumKeyEx (key, i, ifname,
1950 (size = sizeof ifname, &size),
1951 0, 0, 0, &update)) != ERROR_NO_MORE_ITEMS;
1955 char driver[256], classname[256], netname[256];
1956 char adapter[256], ip[256], np[256];
1958 if (res != ERROR_SUCCESS
1959 || RegOpenKeyEx (key, ifname, 0,
1960 KEY_READ, &ifkey) != ERROR_SUCCESS)
1963 if (RegQueryValueEx (ifkey, "Driver", 0,
1964 NULL, (unsigned char *) driver,
1965 (size = sizeof driver, &size)) != ERROR_SUCCESS)
1967 RegCloseKey (ifkey);
1971 strcpy (classname, "System\\CurrentControlSet\\Services\\Class\\");
1972 strcat (classname, driver);
1973 if ((res = RegOpenKeyEx (HKEY_LOCAL_MACHINE, classname,
1974 0, KEY_READ, &subkey)) != ERROR_SUCCESS)
1976 RegCloseKey (ifkey);
1980 if (RegQueryValueEx (subkey, "IPAddress", 0,
1981 NULL, (unsigned char *) ip,
1982 (size = sizeof ip, &size)) == ERROR_SUCCESS
1983 && RegQueryValueEx (subkey, "IPMask", 0,
1984 NULL, (unsigned char *) np,
1985 (size = sizeof np, &size)) == ERROR_SUCCESS)
1987 if ((caddr_t)++ifr > ifc->ifc_buf
1989 - sizeof (struct ifreq))
1996 sa = (struct sockaddr_in *) &ifr->ifr_addr;
1997 sa->sin_addr.s_addr = cygwin_inet_addr (ip);
1998 sa->sin_family = AF_INET;
2001 case SIOCGIFBRDADDR:
2002 lip = cygwin_inet_addr (ip);
2003 lnp = cygwin_inet_addr (np);
2004 sa = (struct sockaddr_in *) &ifr->ifr_broadaddr;
2005 sa->sin_addr.s_addr = lip & lnp | ~lnp;
2006 sa->sin_family = AF_INET;
2009 case SIOCGIFNETMASK:
2010 sa = (struct sockaddr_in *) &ifr->ifr_netmask;
2011 sa->sin_addr.s_addr = cygwin_inet_addr (np);
2012 sa->sin_family = AF_INET;
2016 so = &ifr->ifr_hwaddr;
2017 memset (so->sa_data, 0, IFHWADDRLEN);
2018 so->sa_family = AF_INET;
2021 ifr->ifr_metric = 1;
2024 ifr->ifr_mtu = 1500;
2029 RegCloseKey (subkey);
2031 strcpy (netname, "System\\CurrentControlSet\\Services\\Class\\Net\\");
2032 strcat (netname, ifname);
2034 if (RegOpenKeyEx (HKEY_LOCAL_MACHINE, netname,
2035 0, KEY_READ, &subkey) != ERROR_SUCCESS)
2037 RegCloseKey (ifkey);
2042 if (RegQueryValueEx (subkey, "AdapterName", 0,
2043 NULL, (unsigned char *) adapter,
2044 (size = sizeof adapter, &size)) == ERROR_SUCCESS
2045 && strcasematch (adapter, "MS$PPP"))
2048 strcpy (ifr->ifr_name, "ppp");
2049 strcat (ifr->ifr_name, ppp);
2054 strcpy (ifr->ifr_name, "eth");
2055 strcat (ifr->ifr_name, eth);
2058 RegCloseKey (subkey);
2059 RegCloseKey (ifkey);
2068 /* Set the correct length */
2069 ifc->ifc_len = cnt * sizeof (struct ifreq);
2073 get_ifconf (struct ifconf *ifc, int what)
2075 unsigned long lip, lnp;
2076 struct sockaddr_in *sa;
2078 if (check_null_invalid_struct_errno (ifc))
2081 /* Union maps buffer to correct struct */
2082 struct ifreq *ifr = ifc->ifc_req;
2084 /* Ensure we have space for two struct ifreqs, fail if not. */
2085 if (ifc->ifc_len < (int) (2 * sizeof (struct ifreq)))
2091 /* Set up interface lo0 first */
2092 strcpy (ifr->ifr_name, "lo");
2093 memset (&ifr->ifr_addr, '\0', sizeof (ifr->ifr_addr));
2098 sa = (struct sockaddr_in *) &ifr->ifr_addr;
2099 sa->sin_addr.s_addr = htonl (INADDR_LOOPBACK);
2100 sa->sin_family = AF_INET;
2103 case SIOCGIFBRDADDR:
2104 lip = htonl (INADDR_LOOPBACK);
2105 lnp = cygwin_inet_addr ("255.0.0.0");
2106 sa = (struct sockaddr_in *) &ifr->ifr_broadaddr;
2107 sa->sin_addr.s_addr = lip & lnp | ~lnp;
2108 sa->sin_family = AF_INET;
2111 case SIOCGIFNETMASK:
2112 sa = (struct sockaddr_in *) &ifr->ifr_netmask;
2113 sa->sin_addr.s_addr = cygwin_inet_addr ("255.0.0.0");
2114 sa->sin_family = AF_INET;
2118 ifr->ifr_hwaddr.sa_family = AF_INET;
2119 memset (ifr->ifr_hwaddr.sa_data, 0, IFHWADDRLEN);
2122 ifr->ifr_metric = 1;
2125 /* This funny value is returned by `ifconfig lo' on Linux 2.2 kernel. */
2126 ifr->ifr_mtu = 3924;
2133 OSVERSIONINFO os_version_info;
2134 memset (&os_version_info, 0, sizeof os_version_info);
2135 os_version_info.dwOSVersionInfoSize = sizeof (OSVERSIONINFO);
2136 GetVersionEx (&os_version_info);
2137 if (wincap.has_ip_helper_lib ())
2138 get_2k_ifconf (ifc, what);
2139 else if (wincap.is_winnt ())
2140 get_nt_ifconf (ifc, what);
2142 get_95_ifconf (ifc, what);
2146 /* exported as rcmd: standards? */
2148 cygwin_rcmd (char **ahost, unsigned short inport, char *locuser,
2149 char *remuser, char *cmd, int *fd2p)
2153 sigframe thisframe (mainthread);
2155 if (check_null_invalid_struct_errno (ahost) ||
2156 check_null_empty_str_errno (*ahost) ||
2157 (locuser && check_null_empty_str_errno (locuser)) ||
2158 (remuser && check_null_str_errno (remuser)))
2159 return (int) INVALID_SOCKET;
2161 cygheap_fdnew res_fd;
2167 cygheap_fdnew newfd (res_fd, false);
2173 res = rcmd (ahost, inport, locuser, remuser, cmd, fd2p ? &fd2s : NULL);
2174 if (res == (int) INVALID_SOCKET)
2178 fdsock (res_fd, "/dev/tcp", res);
2183 fdsock (*fd2p, "/dev/tcp", fd2s);
2186 syscall_printf ("%d = rcmd (...)", res);
2190 /* exported as rresvport: standards? */
2192 cygwin_rresvport (int *port)
2195 sigframe thisframe (mainthread);
2197 if (check_null_invalid_struct_errno (port))
2200 cygheap_fdnew res_fd;
2205 res = rresvport (port);
2207 if (res != (int) INVALID_SOCKET)
2209 fdsock (res_fd, "/dev/tcp", res);
2214 syscall_printf ("%d = rresvport (%d)", res, port ? *port : 0);
2218 /* exported as rexec: standards? */
2220 cygwin_rexec (char **ahost, unsigned short inport, char *locuser,
2221 char *password, char *cmd, int *fd2p)
2225 sigframe thisframe (mainthread);
2227 if (check_null_invalid_struct_errno (ahost) ||
2228 check_null_empty_str_errno (*ahost) ||
2229 (locuser && check_null_empty_str_errno (locuser)) ||
2230 (password && check_null_str_errno (password)))
2231 return (int) INVALID_SOCKET;
2233 cygheap_fdnew res_fd;
2238 cygheap_fdnew newfd (res_fd);
2243 res = rexec (ahost, inport, locuser, password, cmd, fd2p ? &fd2s : NULL);
2244 if (res == (int) INVALID_SOCKET)
2248 fdsock (res_fd, "/dev/tcp", res);
2252 fdsock (*fd2p, "/dev/tcp", fd2s);
2255 syscall_printf ("%d = rexec (...)", res);
2259 /* socketpair: standards? */
2260 /* Win32 supports AF_INET only, so ignore domain and protocol arguments */
2262 socketpair (int family, int type, int protocol, int *sb)
2265 SOCKET insock, outsock, newsock;
2266 struct sockaddr_in sock_in, sock_out;
2270 if (__check_null_invalid_struct_errno (sb, 2 * sizeof(int)))
2273 if (family != AF_LOCAL && family != AF_INET)
2275 set_errno (EAFNOSUPPORT);
2278 if (type != SOCK_STREAM && type != SOCK_DGRAM)
2280 set_errno (EPROTOTYPE);
2283 if ((family == AF_LOCAL && protocol != PF_UNSPEC && protocol != PF_LOCAL)
2284 || (family == AF_INET && protocol != PF_UNSPEC && protocol != PF_INET))
2286 set_errno (EPROTONOSUPPORT);
2295 cygheap_fdnew sb1 (sb0, false);
2302 /* create the first socket */
2303 newsock = socket (AF_INET, type, 0);
2304 if (newsock == INVALID_SOCKET)
2306 debug_printf ("first socket call failed");
2307 set_winsock_errno ();
2311 /* bind the socket to any unused port */
2312 sock_in.sin_family = AF_INET;
2313 sock_in.sin_port = 0;
2314 sock_in.sin_addr.s_addr = INADDR_ANY;
2315 if (bind (newsock, (struct sockaddr *) &sock_in, sizeof (sock_in)) < 0)
2317 debug_printf ("bind failed");
2318 set_winsock_errno ();
2319 closesocket (newsock);
2322 len = sizeof (sock_in);
2323 if (getsockname (newsock, (struct sockaddr *) &sock_in, &len) < 0)
2325 debug_printf ("getsockname error");
2326 set_winsock_errno ();
2327 closesocket (newsock);
2331 /* For stream sockets, create a listener */
2332 if (type == SOCK_STREAM)
2333 listen (newsock, 2);
2335 /* create a connecting socket */
2336 outsock = socket (AF_INET, type, 0);
2337 if (outsock == INVALID_SOCKET)
2339 debug_printf ("second socket call failed");
2340 set_winsock_errno ();
2341 closesocket (newsock);
2345 /* For datagram sockets, bind the 2nd socket to an unused address, too */
2346 if (type == SOCK_DGRAM)
2348 sock_out.sin_family = AF_INET;
2349 sock_out.sin_port = 0;
2350 sock_out.sin_addr.s_addr = INADDR_ANY;
2351 if (bind (outsock, (struct sockaddr *) &sock_out, sizeof (sock_out)) < 0)
2353 debug_printf ("bind failed");
2354 set_winsock_errno ();
2355 closesocket (newsock);
2356 closesocket (outsock);
2359 len = sizeof (sock_out);
2360 if (getsockname (outsock, (struct sockaddr *) &sock_out, &len) < 0)
2362 debug_printf ("getsockname error");
2363 set_winsock_errno ();
2364 closesocket (newsock);
2365 closesocket (outsock);
2370 /* Force IP address to loopback */
2371 sock_in.sin_addr.s_addr = htonl (INADDR_LOOPBACK);
2372 if (type == SOCK_DGRAM)
2373 sock_out.sin_addr.s_addr = htonl (INADDR_LOOPBACK);
2376 if (connect (outsock, (struct sockaddr *) &sock_in,
2377 sizeof (sock_in)) < 0)
2379 debug_printf ("connect error");
2380 set_winsock_errno ();
2381 closesocket (newsock);
2382 closesocket (outsock);
2386 if (type == SOCK_STREAM)
2388 /* For stream sockets, accept the connection and close the listener */
2389 len = sizeof (sock_in);
2390 insock = accept (newsock, (struct sockaddr *) &sock_in, &len);
2391 if (insock == INVALID_SOCKET)
2393 debug_printf ("accept error");
2394 set_winsock_errno ();
2395 closesocket (newsock);
2396 closesocket (outsock);
2399 closesocket (newsock);
2403 /* For datagram sockets, connect the 2nd socket */
2404 if (connect (newsock, (struct sockaddr *) &sock_out,
2405 sizeof (sock_out)) < 0)
2407 debug_printf ("connect error");
2408 set_winsock_errno ();
2409 closesocket (newsock);
2410 closesocket (outsock);
2418 if (family == AF_LOCAL)
2420 fhandler_socket *fh;
2423 type == SOCK_STREAM ? "/dev/streamsocket" : "/dev/dgsocket",
2425 fh->set_sun_path ("");
2426 fh->set_addr_family (AF_LOCAL);
2428 type == SOCK_STREAM ? "/dev/streamsocket" : "/dev/dgsocket",
2430 fh->set_sun_path ("");
2431 fh->set_addr_family (AF_LOCAL);
2435 fdsock (sb[0], type == SOCK_STREAM ? "/dev/tcp" : "/dev/udp",
2436 insock)->set_addr_family (AF_INET);
2437 fdsock (sb[1], type == SOCK_STREAM ? "/dev/tcp" : "/dev/udp",
2438 outsock)->set_addr_family (AF_INET);
2442 syscall_printf ("%d = socketpair (...)", res);
2446 /* sethostent: standards? */
2452 /* endhostent: standards? */
2458 /* exported as recvmsg: standards? */
2460 cygwin_recvmsg(int s, struct msghdr *msg, int flags)
2466 struct iovec *iov = msg->msg_iov;
2468 for(i = 0; i < msg->msg_iovlen; ++i)
2469 tot += iov[i].iov_len;
2470 buf = (char *) malloc(tot);
2471 if (tot != 0 && buf == NULL) {
2475 nb = ret = cygwin_recvfrom (s, buf, tot, flags,
2476 (struct sockaddr *) msg->msg_name, (int *) &msg->msg_namelen);
2479 ssize_t cnt = min(nb, iov->iov_len);
2481 memcpy (iov->iov_base, p, cnt);
2490 /* exported as sendmsg: standards? */
2492 cygwin_sendmsg(int s, const struct msghdr *msg, int flags)
2498 struct iovec *iov = msg->msg_iov;
2500 for(i = 0; i < msg->msg_iovlen; ++i)
2501 tot += iov[i].iov_len;
2502 buf = (char *) malloc(tot);
2503 if (tot != 0 && buf == NULL) {
2508 for (i = 0; i < msg->msg_iovlen; ++i) {
2509 memcpy (p, iov[i].iov_base, iov[i].iov_len);
2510 p += iov[i].iov_len;
2512 ret = cygwin_sendto (s, buf, tot, flags,
2513 (struct sockaddr *) msg->msg_name, msg->msg_namelen);