From: Guus Sliepen <guus@tinc-vpn.org>
Date: Tue, 29 Jul 2003 22:59:01 +0000 (+0000)
Subject: Native Windows support.
X-Git-Tag: release-1.0~34
X-Git-Url: http://git.tinc-vpn.org/git/browse?a=commitdiff_plain;h=721e4caee0f7c6e003c297c95fb6d93bd4102219;p=tinc

Native Windows support.
---

diff --git a/lib/dropin.c b/lib/dropin.c
index c92c0b81..d4756010 100644
--- a/lib/dropin.c
+++ b/lib/dropin.c
@@ -17,7 +17,7 @@
     along with this program; if not, write to the Free Software
     Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
 
-    $Id: dropin.c,v 1.1.2.17 2003/07/28 22:06:09 guus Exp $
+    $Id: dropin.c,v 1.1.2.18 2003/07/29 22:59:00 guus Exp $
 */
 
 #include "system.h"
@@ -139,7 +139,7 @@ int asprintf(char **buf, const char *fmt, ...)
 	va_end(ap);
 
 	if(status >= 0)
-		*buf = xrealloc(*buf, status);
+		*buf = xrealloc(*buf, status + 1);
 
 	if(status > len - 1) {
 		len = status;
@@ -159,3 +159,15 @@ int gettimeofday(struct timeval *tv, void *tz) {
 	return 0;
 }
 #endif
+
+#ifndef HAVE_RANDOM
+#include <openssl/rand.h>
+
+long int random(void) {
+	long int x;
+	
+	RAND_pseudo_bytes((unsigned char *)&x, sizeof(x));
+
+	return x;
+}
+#endif
diff --git a/lib/dropin.h b/lib/dropin.h
index 3afa69cc..a3afa719 100644
--- a/lib/dropin.h
+++ b/lib/dropin.h
@@ -17,7 +17,7 @@
     along with this program; if not, write to the Free Software
     Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
 
-    $Id: dropin.h,v 1.1.2.13 2003/07/18 13:42:35 guus Exp $
+    $Id: dropin.h,v 1.1.2.14 2003/07/29 22:59:00 guus Exp $
 */
 
 #ifndef __DROPIN_H__
@@ -43,4 +43,12 @@ extern int getnameinfo(const struct sockaddr *sa, size_t salen, char *host,
 					   size_t hostlen, char *serv, size_t servlen, int flags);
 #endif
 
+#ifndef HAVE_GETTIMEOFDAY
+extern int gettimeofday(struct timeval *, void *);
+#endif
+
+#ifndef HAVE_RANDOM
+extern long int random(void);
+#endif
+
 #endif							/* __DROPIN_H__ */
diff --git a/src/logger.c b/src/logger.c
index 871f2c14..f85bd152 100644
--- a/src/logger.c
+++ b/src/logger.c
@@ -17,7 +17,7 @@
     along with this program; if not, write to the Free Software
     Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
 
-    $Id: logger.c,v 1.1.2.7 2003/07/29 10:50:15 guus Exp $
+    $Id: logger.c,v 1.1.2.8 2003/07/29 22:59:00 guus Exp $
 */
 
 #include "system.h"
@@ -65,6 +65,7 @@ void logger(int priority, const char *format, ...) {
 		case LOGMODE_STDERR:
 			vfprintf(stderr, format, ap);
 			fprintf(stderr, "\n");
+			fflush(stderr);
 			break;
 		case LOGMODE_FILE:
 			fprintf(logfile, "%ld %s[%d]: ", time(NULL), logident, logpid);
diff --git a/src/meta.c b/src/meta.c
index e818b0b4..0d103c03 100644
--- a/src/meta.c
+++ b/src/meta.c
@@ -17,7 +17,7 @@
     along with this program; if not, write to the Free Software
     Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
 
-    $Id: meta.c,v 1.1.2.37 2003/07/22 20:55:19 guus Exp $
+    $Id: meta.c,v 1.1.2.38 2003/07/29 22:59:00 guus Exp $
 */
 
 #include "system.h"
@@ -52,7 +52,7 @@ bool send_meta(connection_t *c, char *buffer, int length)
 		bufp = buffer;
 
 	while(length) {
-		result = write(c->socket, bufp, length);
+		result = send(c->socket, bufp, length, 0);
 		if(result <= 0) {
 			if(errno == EINTR)
 				continue;
@@ -114,7 +114,7 @@ bool receive_meta(connection_t *c)
 	   - If not, keep stuff in buffer and exit.
 	 */
 
-	lenin = read(c->socket, c->buffer + c->buflen, MAXBUFSIZE - c->buflen);
+	lenin = recv(c->socket, c->buffer + c->buflen, MAXBUFSIZE - c->buflen, 0);
 
 	if(lenin <= 0) {
 		if(lenin == 0) {
diff --git a/src/mingw/device.c b/src/mingw/device.c
index d005a63b..dfda0895 100644
--- a/src/mingw/device.c
+++ b/src/mingw/device.c
@@ -17,7 +17,7 @@
     along with this program; if not, write to the Free Software
     Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
 
-    $Id: device.c,v 1.1.2.5 2003/07/29 12:38:49 guus Exp $
+    $Id: device.c,v 1.1.2.6 2003/07/29 22:59:01 guus Exp $
 */
 
 #include "system.h"
@@ -51,7 +51,8 @@
 /* FIXME: This only works for Windows 2000 */
 #define OSTYPE 5
 
-HANDLE device_fd = INVALID_HANDLE_VALUE;
+int device_fd = 0;
+HANDLE device_handle = INVALID_HANDLE_VALUE;
 char *device = NULL;
 char *iface = NULL;
 char *device_info = NULL;
@@ -59,6 +60,72 @@ char *device_info = NULL;
 int device_total_in = 0;
 int device_total_out = 0;
 
+DWORD WINAPI tapreader(void *bla) {
+	int sock, err, status;
+	struct addrinfo *ai;
+	struct addrinfo hint = {
+		.ai_family = AF_UNSPEC,
+		.ai_socktype = SOCK_DGRAM,
+		.ai_protocol = IPPROTO_UDP,
+		.ai_flags = 0,
+	};
+	char buf[MTU];
+	long len;
+	OVERLAPPED overlapped;
+
+	/* Open a socket to the parent process */
+
+	err = getaddrinfo(NULL, "12345", &hint, &ai);
+
+	if(err || !ai) {
+		logger(LOG_ERR, _("System call `%s' failed: %s"), "getaddrinfo", gai_strerror(errno));
+		return -1;
+	}
+
+	sock = socket(ai->ai_family, ai->ai_socktype, ai->ai_protocol);
+
+	freeaddrinfo(ai);
+
+	if(sock < 0) {
+		logger(LOG_ERR, _("System call `%s' failed: %s"), "socket", strerror(errno));
+		return -1;
+	}
+
+	if(connect(sock, ai->ai_addr, ai->ai_addrlen)) {
+		logger(LOG_ERR, _("System call `%s' failed: %s"), "connect", strerror(errno));
+		return -1;
+	}
+
+	logger(LOG_DEBUG, _("Tap reader running"));
+
+	/* Read from tap device and send to parent */
+
+	overlapped.hEvent = CreateEvent(NULL, TRUE, FALSE, NULL);
+	
+	for(;;) {
+		overlapped.Offset = 0;
+		overlapped.OffsetHigh = 0;
+		ResetEvent(overlapped.hEvent);
+
+		status = ReadFile(device_handle, buf, sizeof(buf), &len, &overlapped);
+
+		if(!status) {
+			if(GetLastError() == ERROR_IO_PENDING) {
+				WaitForSingleObject(overlapped.hEvent, INFINITE);
+				if(!GetOverlappedResult(device_handle, &overlapped, &len, FALSE))
+					continue;
+			} else {
+				logger(LOG_ERR, _("Error while reading from %s %s: %s"), device_info,
+					   device, strerror(errno));
+				return -1;
+			}
+		}
+
+		if(send(sock, buf, len, 0) <= 0)
+			return -1;
+	}
+}
+
 bool setup_device(void)
 {
 	HKEY key, key2;
@@ -68,11 +135,21 @@ bool setup_device(void)
 	char adapterid[1024];
 	char adaptername[1024];
 	char tapname[1024];
-	char gelukt = 0;
 	long len;
 
 	bool found = false;
 
+	int sock, err;
+	HANDLE thread;
+
+	struct addrinfo *ai;
+	struct addrinfo hint = {
+		.ai_family = AF_UNSPEC,
+		.ai_socktype = SOCK_DGRAM,
+		.ai_protocol = IPPROTO_UDP,
+		.ai_flags = AI_PASSIVE,
+	};
+
 	cp();
 
 	get_config_string(lookup_config(config_tree, "Device"), &device);
@@ -117,8 +194,8 @@ bool setup_device(void)
 		}
 
 		snprintf(tapname, sizeof(tapname), USERMODEDEVICEDIR "%s" TAPSUFFIX, adapterid);
-		device_fd = CreateFile(tapname, GENERIC_WRITE | GENERIC_READ, 0, 0, OPEN_EXISTING, FILE_ATTRIBUTE_SYSTEM, 0);
-		if(device_fd != INVALID_HANDLE_VALUE) {
+		device_handle = CreateFile(tapname, GENERIC_WRITE | GENERIC_READ, 0, 0, OPEN_EXISTING, FILE_ATTRIBUTE_SYSTEM | FILE_FLAG_OVERLAPPED, 0);
+		if(device_handle != INVALID_HANDLE_VALUE) {
 			found = true;
 			break;
 		}
@@ -129,24 +206,27 @@ bool setup_device(void)
 		return false;
 	}
 
-	device = adapterid;
-	iface = adaptername;
+	if(!device)
+		device = xstrdup(adapterid);
+
+	if(!iface)
+		iface = xstrdup(adaptername);
 
 	/* Try to open the corresponding tap device */
 
-	if(device_fd == INVALID_HANDLE_VALUE) {
+	if(device_handle == INVALID_HANDLE_VALUE) {
 		snprintf(tapname, sizeof(tapname), USERMODEDEVICEDIR "%s" TAPSUFFIX, device);
-		device_fd = CreateFile(tapname, GENERIC_WRITE | GENERIC_READ, 0, 0, OPEN_EXISTING, FILE_ATTRIBUTE_SYSTEM, 0);
+		device_handle = CreateFile(tapname, GENERIC_WRITE | GENERIC_READ, 0, 0, OPEN_EXISTING, FILE_ATTRIBUTE_SYSTEM | FILE_FLAG_OVERLAPPED, 0);
 	}
 	
-	if(device_fd == INVALID_HANDLE_VALUE) {
+	if(device_handle == INVALID_HANDLE_VALUE) {
 		logger(LOG_ERR, _("%s (%s) is no a usable Windows tap device!"), device, iface);
 		return false;
 	}
 
 	/* Get MAC address from tap device */
 
-	if(!DeviceIoControl(device_fd, TAP_IOCTL_GET_MAC, mymac.x, sizeof(mymac.x), mymac.x, sizeof(mymac.x), &len, 0)) {
+	if(!DeviceIoControl(device_handle, TAP_IOCTL_GET_MAC, mymac.x, sizeof(mymac.x), mymac.x, sizeof(mymac.x), &len, 0)) {
 		logger(LOG_ERR, _("Could not get MAC address from Windows tap device!"));
 		return false;
 	}
@@ -155,6 +235,52 @@ bool setup_device(void)
 		overwrite_mac = 1;
 	}
 
+	/* Create a listening socket */
+
+	err = getaddrinfo(NULL, "12345", &hint, &ai);
+
+	if(err || !ai) {
+		logger(LOG_ERR, _("System call `%s' failed: %s"), "getaddrinfo", gai_strerror(errno));
+		return false;
+	}
+
+	sock = socket(ai->ai_family, ai->ai_socktype, ai->ai_protocol);
+
+	if(sock < 0) {
+		logger(LOG_ERR, _("System call `%s' failed: %s"), "socket", strerror(errno));
+		return false;
+	}
+
+	if(bind(sock, ai->ai_addr, ai->ai_addrlen)) {
+		logger(LOG_ERR, _("System call `%s' failed: %s"), "bind", strerror(errno));
+		return false;
+	}
+
+	freeaddrinfo(ai);
+
+	if(listen(sock, 1)) {
+		logger(LOG_ERR, _("System call `%s' failed: %s"), "listen", strerror(errno));
+		return false;
+	}
+
+	/* Start the tap reader */
+
+	thread = CreateThread(NULL, 0, tapreader, NULL, 0, NULL);
+
+	if(!thread) {
+		logger(LOG_ERR, _("System call `%s' failed: %s"), "CreateThread", strerror(errno));
+		return false;
+	}
+
+	/* Wait for the tap reader to connect back to us */
+
+	if((device_fd = accept(sock, NULL, 0)) == -1) {
+		logger(LOG_ERR, _("System call `%s' failed: %s"), "accept", strerror(errno));
+		return false;
+	}
+
+	closesocket(sock);
+
 	device_info = _("Windows tap device");
 
 	logger(LOG_INFO, _("%s (%s) is a %s"), device, iface, device_info);
@@ -166,16 +292,16 @@ void close_device(void)
 {
 	cp();
 
-	CloseHandle(device_fd);
+	CloseHandle(device_handle);
 }
 
 bool read_packet(vpn_packet_t *packet)
 {
-	long lenin;
+	int lenin;
 
 	cp();
 
-	if(!ReadFile(device_fd, packet->data, MTU, &lenin, NULL)) {
+	if((lenin = recv(device_fd, packet->data, MTU, 0)) <= 0) {
 		logger(LOG_ERR, _("Error while reading from %s %s: %s"), device_info,
 			   device, strerror(errno));
 		return false;
@@ -194,13 +320,14 @@ bool read_packet(vpn_packet_t *packet)
 bool write_packet(vpn_packet_t *packet)
 {
 	long lenout;
+	OVERLAPPED overlapped = {0};
 
 	cp();
 
 	ifdebug(TRAFFIC) logger(LOG_DEBUG, _("Writing packet of %d bytes to %s"),
 			   packet->len, device_info);
 
-	if(!WriteFile(device_fd, packet->data, packet->len, &lenout, NULL)) {
+	if(!WriteFile(device_handle, packet->data, packet->len, &lenout, &overlapped)) {
 		logger(LOG_ERR, _("Error while writing to %s %s"), device_info, device);
 		return false;
 	}
diff --git a/src/net.c b/src/net.c
index c4637dab..e1580e65 100644
--- a/src/net.c
+++ b/src/net.c
@@ -17,7 +17,7 @@
     along with this program; if not, write to the Free Software
     Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
 
-    $Id: net.c,v 1.35.4.194 2003/07/29 10:50:15 guus Exp $
+    $Id: net.c,v 1.35.4.195 2003/07/29 22:59:00 guus Exp $
 */
 
 #include "system.h"
@@ -39,6 +39,7 @@
 #include "protocol.h"
 #include "route.h"
 #include "subnet.h"
+#include "xalloc.h"
 
 bool do_purge = false;
 
@@ -153,7 +154,7 @@ void terminate_connection(connection_t *c, bool report)
 		c->node->connection = NULL;
 
 	if(c->socket)
-		close(c->socket);
+		closesocket(c->socket);
 
 	if(c->edge) {
 		if(report)
@@ -254,7 +255,7 @@ static void check_network_activity(fd_set * f)
 					ifdebug(CONNECTIONS) logger(LOG_DEBUG,
 							   _("Error while connecting to %s (%s): %s"),
 							   c->name, c->hostname, strerror(result));
-					close(c->socket);
+					closesocket(c->socket);
 					do_outgoing_connection(c);
 					continue;
 				}
diff --git a/src/net.h b/src/net.h
index 8ab33615..f1494666 100644
--- a/src/net.h
+++ b/src/net.h
@@ -17,7 +17,7 @@
     along with this program; if not, write to the Free Software
     Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
 
-    $Id: net.h,v 1.9.4.67 2003/07/24 12:08:15 guus Exp $
+    $Id: net.h,v 1.9.4.68 2003/07/29 22:59:00 guus Exp $
 */
 
 #ifndef __TINC_NET_H__
@@ -140,4 +140,8 @@ extern void terminate_connection(struct connection_t *, bool);
 extern void flush_queue(struct node_t *);
 extern bool read_rsa_public_key(struct connection_t *);
 
+#ifndef HAVE_MINGW
+#define closesocket(s) close(s)
+#endif
+
 #endif							/* __TINC_NET_H__ */
diff --git a/src/net_setup.c b/src/net_setup.c
index 6f7f70ad..3695e18e 100644
--- a/src/net_setup.c
+++ b/src/net_setup.c
@@ -17,7 +17,7 @@
     along with this program; if not, write to the Free Software
     Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
 
-    $Id: net_setup.c,v 1.1.2.39 2003/07/23 22:17:31 guus Exp $
+    $Id: net_setup.c,v 1.1.2.40 2003/07/29 22:59:00 guus Exp $
 */
 
 #include "system.h"
@@ -444,14 +444,14 @@ bool setup_myself(void)
 
 	/* Open sockets */
 
-	memset(&hint, 0, sizeof(hint));
-
 	get_config_string(lookup_config(config_tree, "BindToAddress"), &address);
 
-	hint.ai_family = addressfamily;
-	hint.ai_socktype = SOCK_STREAM;
-	hint.ai_protocol = IPPROTO_TCP;
-	hint.ai_flags = AI_PASSIVE;
+	hint = (struct addrinfo) {
+		.ai_family = addressfamily,
+		.ai_socktype = SOCK_STREAM,
+		.ai_protocol = IPPROTO_TCP,
+		.ai_flags = AI_PASSIVE,
+	};
 
 	err = getaddrinfo(address, myport, &hint, &ai);
 
diff --git a/src/net_socket.c b/src/net_socket.c
index 5f9e2173..78e1ad2c 100644
--- a/src/net_socket.c
+++ b/src/net_socket.c
@@ -17,7 +17,7 @@
     along with this program; if not, write to the Free Software
     Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
 
-    $Id: net_socket.c,v 1.1.2.32 2003/07/28 22:06:09 guus Exp $
+    $Id: net_socket.c,v 1.1.2.33 2003/07/29 22:59:00 guus Exp $
 */
 
 #include "system.h"
@@ -70,7 +70,7 @@ int setup_listen_socket(const sockaddr_t *sa)
 	flags = fcntl(nfd, F_GETFL);
 
 	if(fcntl(nfd, F_SETFL, flags | O_NONBLOCK) < 0) {
-		close(nfd);
+		closesocket(nfd);
 		logger(LOG_ERR, _("System call `%s' failed: %s"), "fcntl",
 			   strerror(errno));
 		return -1;
@@ -98,7 +98,7 @@ int setup_listen_socket(const sockaddr_t *sa)
 		strncpy(ifr.ifr_ifrn.ifrn_name, iface, IFNAMSIZ);
 
 		if(setsockopt(nfd, SOL_SOCKET, SO_BINDTODEVICE, &ifr, sizeof(ifr))) {
-			close(nfd);
+			closesocket(nfd);
 			logger(LOG_ERR, _("Can't bind to interface %s: %s"), iface,
 				   strerror(errno));
 			return -1;
@@ -109,7 +109,7 @@ int setup_listen_socket(const sockaddr_t *sa)
 	}
 
 	if(bind(nfd, &sa->sa, SALEN(sa->sa))) {
-		close(nfd);
+		closesocket(nfd);
 		addrstr = sockaddr2hostname(sa);
 		logger(LOG_ERR, _("Can't bind to %s/tcp: %s"), addrstr,
 			   strerror(errno));
@@ -118,7 +118,7 @@ int setup_listen_socket(const sockaddr_t *sa)
 	}
 
 	if(listen(nfd, 3)) {
-		close(nfd);
+		closesocket(nfd);
 		logger(LOG_ERR, _("System call `%s' failed: %s"), "listen",
 			   strerror(errno));
 		return -1;
@@ -149,7 +149,7 @@ int setup_vpn_in_socket(const sockaddr_t *sa)
 #ifdef O_NONBLOCK
 	flags = fcntl(nfd, F_GETFL);
 	if(fcntl(nfd, F_SETFL, flags | O_NONBLOCK) < 0) {
-		close(nfd);
+		closesocket(nfd);
 		logger(LOG_ERR, _("System call `%s' failed: %s"), "fcntl",
 			   strerror(errno));
 		return -1;
@@ -166,7 +166,7 @@ int setup_vpn_in_socket(const sockaddr_t *sa)
 		strncpy(ifr.ifr_ifrn.ifrn_name, iface, IFNAMSIZ);
 
 		if(setsockopt(nfd, SOL_SOCKET, SO_BINDTODEVICE, &ifr, sizeof(ifr))) {
-			close(nfd);
+			closesocket(nfd);
 			logger(LOG_ERR, _("Can't bind to interface %s: %s"), iface,
 				   strerror(errno));
 			return -1;
@@ -175,7 +175,7 @@ int setup_vpn_in_socket(const sockaddr_t *sa)
 #endif
 
 	if(bind(nfd, &sa->sa, SALEN(sa->sa))) {
-		close(nfd);
+		closesocket(nfd);
 		addrstr = sockaddr2hostname(sa);
 		logger(LOG_ERR, _("Can't bind to %s/udp: %s"), addrstr,
 			   strerror(errno));
@@ -308,7 +308,7 @@ begin:
 			return;
 		}
 
-		close(c->socket);
+		closesocket(c->socket);
 
 		ifdebug(CONNECTIONS) logger(LOG_ERR, _("%s: %s"), c->hostname, strerror(errno));
 
diff --git a/src/netutl.c b/src/netutl.c
index cd50792f..1ec6e5a8 100644
--- a/src/netutl.c
+++ b/src/netutl.c
@@ -17,7 +17,7 @@
     along with this program; if not, write to the Free Software
     Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
 
-    $Id: netutl.c,v 1.12.4.49 2003/07/24 12:08:15 guus Exp $
+    $Id: netutl.c,v 1.12.4.50 2003/07/29 22:59:00 guus Exp $
 */
 
 #include "system.h"
@@ -36,16 +36,15 @@ bool hostnames = false;
 */
 struct addrinfo *str2addrinfo(const char *address, const char *service, int socktype)
 {
-	struct addrinfo hint, *ai;
+	struct addrinfo *ai;
+	struct addrinfo hint = {
+		.ai_family = addressfamily,
+		.ai_socktype = socktype,
+	};
 	int err;
 
 	cp();
 
-	memset(&hint, 0, sizeof(hint));
-
-	hint.ai_family = addressfamily;
-	hint.ai_socktype = socktype;
-
 	err = getaddrinfo(address, service, &hint, &ai);
 
 	if(err) {
@@ -59,18 +58,17 @@ struct addrinfo *str2addrinfo(const char *address, const char *service, int sock
 
 sockaddr_t str2sockaddr(const char *address, const char *port)
 {
-	struct addrinfo hint, *ai;
+	struct addrinfo *ai;
+	struct addrinfo hint = {
+		.ai_family = AF_UNSPEC,
+		.ai_flags = AI_NUMERICHOST,
+		.ai_socktype = SOCK_STREAM,
+	};
 	sockaddr_t result;
 	int err;
 
 	cp();
 
-	memset(&hint, 0, sizeof(hint));
-
-	hint.ai_family = AF_UNSPEC;
-	hint.ai_flags = AI_NUMERICHOST;
-	hint.ai_socktype = SOCK_STREAM;
-
 	err = getaddrinfo(address, port, &hint, &ai);
 
 	if(err || !ai) {
diff --git a/src/protocol.h b/src/protocol.h
index 0eae830d..7a32a17a 100644
--- a/src/protocol.h
+++ b/src/protocol.h
@@ -17,7 +17,7 @@
     along with this program; if not, write to the Free Software
     Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
 
-    $Id: protocol.h,v 1.5.4.42 2003/07/29 10:50:15 guus Exp $
+    $Id: protocol.h,v 1.5.4.43 2003/07/29 22:59:00 guus Exp $
 */
 
 #ifndef __TINC_PROTOCOL_H__
@@ -29,6 +29,12 @@
 
 #define PROT_CURRENT 17
 
+/* Silly Windows */
+
+#ifdef ERROR
+#undef ERROR
+#endif
+
 /* Request numbers */
 
 typedef enum request_t {
diff --git a/src/tincd.c b/src/tincd.c
index d2179ab1..6b90de76 100644
--- a/src/tincd.c
+++ b/src/tincd.c
@@ -17,7 +17,7 @@
     along with this program; if not, write to the Free Software
     Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
 
-    $Id: tincd.c,v 1.10.4.77 2003/07/28 22:06:09 guus Exp $
+    $Id: tincd.c,v 1.10.4.78 2003/07/29 22:59:00 guus Exp $
 */
 
 #include "system.h"
@@ -93,6 +93,10 @@ static struct option const long_options[] = {
 	{NULL, 0, NULL, 0}
 };
 
+#ifdef HAVE_MINGW
+static struct WSAData wsa_state;
+#endif
+
 static void usage(bool status)
 {
 	if(status)
@@ -417,6 +421,13 @@ int main(int argc, char **argv, char **envp)
 		exit(1);
 	}
 
+#ifdef HAVE_MINGW
+	if(WSAStartup(MAKEWORD(2, 2), &wsa_state)) {
+		logger(LOG_ERR, _("System call `%s' failed: %s"), "WSAStartup", strerror(errno));
+		exit(1);
+	}
+#endif
+	
 	if(!detach())
 		exit(1);
 		
diff --git a/system.h b/system.h
index d4381dc5..73f7aeb1 100644
--- a/system.h
+++ b/system.h
@@ -115,7 +115,7 @@
 
 #ifdef HAVE_MINGW
 #include <windows.h>
-#include <winsock.h>
+#include <winsock2.h>
 #endif
 
 /* Include localisation support */