#43 Now works on windows, if you set your ip correctly and use a /30 netmask

This commit is contained in:
Erik Ekman 2009-01-25 14:22:07 +00:00
parent 85adeb7eb4
commit 78616d5679
2 changed files with 91 additions and 9 deletions

View file

@ -30,6 +30,7 @@
#include "windows.h" #include "windows.h"
HANDLE dev_handle; HANDLE dev_handle;
struct tun_data data;
#define TAP_CONTROL_CODE(request,method) CTL_CODE(FILE_DEVICE_UNKNOWN, request, method, FILE_ANY_ACCESS) #define TAP_CONTROL_CODE(request,method) CTL_CODE(FILE_DEVICE_UNKNOWN, request, method, FILE_ANY_ACCESS)
#define TAP_IOCTL_CONFIG_TUN TAP_CONTROL_CODE(10, METHOD_BUFFERED) #define TAP_IOCTL_CONFIG_TUN TAP_CONTROL_CODE(10, METHOD_BUFFERED)
@ -224,11 +225,43 @@ next:
RegCloseKey(adapter_key); RegCloseKey(adapter_key);
} }
DWORD WINAPI tun_reader(LPVOID arg)
{
struct tun_data *tun = arg;
char buf[64*1024];
int len;
int res;
OVERLAPPED olpd;
int sock;
sock = open_dns(0, INADDR_ANY);
olpd.hEvent = CreateEvent(NULL, TRUE, FALSE, NULL);
while(TRUE) {
olpd.Offset = 0;
olpd.OffsetHigh = 0;
res = ReadFile(tun->tun, buf, sizeof(buf), (LPDWORD) &len, &olpd);
if (!res) {
WaitForSingleObject(olpd.hEvent, INFINITE);
res = GetOverlappedResult(dev_handle, &olpd, (LPDWORD) &len, FALSE);
printf("Read %d bytes!\n", len);
res = sendto(sock, buf, len, 0, (struct sockaddr*) &(tun->addr),
sizeof(struct sockaddr_in));
printf("send done %d, %02X %02X %02X\n", res, buf[0], buf[1], buf[2]);
}
}
return 0;
}
int int
open_tun(const char *tun_device) open_tun(const char *tun_device)
{ {
char adapter[256]; char adapter[256];
char tapfile[512]; char tapfile[512];
int tunfd;
in_addr_t local;
memset(adapter, 0, sizeof(adapter)); memset(adapter, 0, sizeof(adapter));
get_device(adapter, sizeof(adapter)); get_device(adapter, sizeof(adapter));
@ -238,13 +271,29 @@ open_tun(const char *tun_device)
snprintf(tapfile, sizeof(tapfile), "%s%s.tap", TAP_DEVICE_SPACE, adapter); snprintf(tapfile, sizeof(tapfile), "%s%s.tap", TAP_DEVICE_SPACE, adapter);
printf("Opening device %s\n", tapfile); printf("Opening device %s\n", tapfile);
dev_handle = CreateFile(tapfile, GENERIC_WRITE | GENERIC_READ, 0, 0, OPEN_EXISTING, FILE_ATTRIBUTE_SYSTEM, 0); dev_handle = CreateFile(tapfile, GENERIC_WRITE | GENERIC_READ, 0, 0, OPEN_EXISTING, FILE_ATTRIBUTE_SYSTEM | FILE_FLAG_OVERLAPPED, NULL);
if (dev_handle == INVALID_HANDLE_VALUE) { if (dev_handle == INVALID_HANDLE_VALUE) {
return -1; return -1;
} }
printf("Opened handle: %p\n", dev_handle); printf("Opened handle: %p\n", dev_handle);
return (int) dev_handle;
/* Use a UDP connection to forward packets from tun,
* so we can still use select() in main code.
* A thread does blocking reads on tun device and
* sends data as udp to this socket */
local = htonl(0x7f000001); /* 127.0.0.1 */
tunfd = open_dns(55353, local);
data.tun = dev_handle;
memset(&(data.addr), 0, sizeof(data.addr));
data.addr.sin_family = AF_INET;
data.addr.sin_port = htons(55353);
data.addr.sin_addr.s_addr = local;
CreateThread(NULL, 0, (LPTHREAD_START_ROUTINE)tun_reader, &data, 0, NULL);
return tunfd;
} }
#endif #endif
@ -283,10 +332,19 @@ write_tun(int tun_fd, char *data, size_t len)
#else /* WINDOWS32 */ #else /* WINDOWS32 */
{ {
DWORD written; DWORD written;
WriteFile((HANDLE) tun_fd, data, len, &written, NULL); DWORD res;
if (written != len) { OVERLAPPED olpd;
warn("write_tun");
return 1; olpd.Offset = 0;
olpd.OffsetHigh = 0;
olpd.hEvent = CreateEvent(NULL, TRUE, FALSE, NULL);
res = WriteFile(dev_handle, data, len, &written, &olpd);
if (!res && GetLastError() == ERROR_IO_PENDING) {
WaitForSingleObject(olpd.hEvent, INFINITE);
res = GetOverlappedResult(dev_handle, &olpd, &written, FALSE);
if (written != len) {
return -1;
}
} }
} }
#endif #endif
@ -296,12 +354,28 @@ write_tun(int tun_fd, char *data, size_t len)
ssize_t ssize_t
read_tun(int tun_fd, char *buf, size_t len) read_tun(int tun_fd, char *buf, size_t len)
{ {
#if defined (FREEBSD) || defined (DARWIN) || defined(NETBSD) || defined(WINDOWS32) #ifndef WINDOWS32
#if defined (FREEBSD) || defined (DARWIN) || defined(NETBSD)
/* FreeBSD/Darwin/NetBSD has no header */ /* FreeBSD/Darwin/NetBSD has no header */
return READ(tun_fd, buf + 4, len - 4) + 4; int bytes;
bytes = read(tun_fd, buf + 4, len - 4);
if (bytes < 0) {
return bytes;
} else {
return bytes + 4;
}
#else /* !FREEBSD */ #else /* !FREEBSD */
return READ(tun_fd, buf, len); return read(tun_fd, buf, len);
#endif /* !FREEBSD */ #endif /* !FREEBSD */
#else /* !WINDOWS32 */
int bytes;
bytes = RECV(tun_fd, buf + 4, len, 0);
if (bytes < 0) {
return bytes;
} else {
return bytes + 4;
}
#endif
} }
int int
@ -358,6 +432,8 @@ tun_setip(const char *ip, int netbits)
DWORD len; DWORD len;
BOOL res; BOOL res;
printf("Given IP %s\n", ip);
/* Set device as connected */ /* Set device as connected */
status = 1; status = 1;
res =DeviceIoControl(dev_handle, TAP_IOCTL_SET_MEDIA_STATUS, &status, res =DeviceIoControl(dev_handle, TAP_IOCTL_SET_MEDIA_STATUS, &status,

View file

@ -80,5 +80,11 @@ struct ip
struct in_addr ip_src, ip_dst; /* source and dest address */ struct in_addr ip_src, ip_dst; /* source and dest address */
}; };
DWORD WINAPI tun_reader(LPVOID arg);
struct tun_data {
HANDLE tun;
int sock;
struct sockaddr_in addr;
};
#endif #endif