Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with
or
.
Download ZIP

Comparing changes

Choose two branches to see what’s changed or to start a new pull request. If you need to, you can also compare across forks.

Open a pull request

Create a new pull request by comparing changes across two branches. If you need to, you can also compare across forks.
base fork: joyent/node
base: master
...
head fork: koush/node
Checking mergeability… Don’t worry, you can still create the pull request.
  • 1 commit
  • 4 files changed
  • 0 commit comments
  • 1 contributor
Commits on Oct 28, 2012
@koush koush tun support built into node. this was done, because afaik, there is n…
…o to

way create native windows drivers. need to interface with the windows
registry and call DeviceIOControl.
c454bf8
Showing with 205 additions and 4 deletions.
  1. +10 −4 deps/uv/src/win/fs.c
  2. +44 −0 lib/os.js
  3. +10 −0 make-darwin.sh
  4. +141 −0 src/node_os.cc
View
14 deps/uv/src/win/fs.c
@@ -98,6 +98,12 @@ const WCHAR LONG_PATH_PREFIX[] = L"\\\\?\\";
const WCHAR LONG_PATH_PREFIX_LEN = 4;
+static HANDLE __get_osfhandle(intptr_t fd) {
+ if (fd > 0)
+ return _get_osfhandle(fd);
+ return (HANDLE)-fd;
+}
+
void uv_fs_init() {
_fmode = _O_BINARY;
}
@@ -535,7 +541,7 @@ void fs__read(uv_fs_t* req) {
VERIFY_FD(fd, req);
- handle = (HANDLE) _get_osfhandle(fd);
+ handle = (HANDLE) __get_osfhandle(fd);
if (handle == INVALID_HANDLE_VALUE) {
SET_REQ_RESULT(req, -1);
return;
@@ -582,7 +588,7 @@ void fs__write(uv_fs_t* req) {
VERIFY_FD(fd, req);
- handle = (HANDLE) _get_osfhandle(fd);
+ handle = (HANDLE) __get_osfhandle(fd);
if (handle == INVALID_HANDLE_VALUE) {
SET_REQ_RESULT(req, -1);
return;
@@ -961,7 +967,7 @@ INLINE static void fs__sync_impl(uv_fs_t* req) {
VERIFY_FD(fd, req);
- result = FlushFileBuffers((HANDLE) _get_osfhandle(fd)) ? 0 : -1;
+ result = FlushFileBuffers((HANDLE) __get_osfhandle(fd)) ? 0 : -1;
if (result == -1) {
SET_REQ_WIN32_ERROR(req, GetLastError());
} else {
@@ -1068,7 +1074,7 @@ static void fs__fchmod(uv_fs_t* req) {
VERIFY_FD(fd, req);
- handle = (HANDLE)_get_osfhandle(fd);
+ handle = (HANDLE)__get_osfhandle(fd);
nt_status = pNtQueryInformationFile(handle,
&io_status,
View
44 lib/os.js
@@ -32,6 +32,50 @@ exports.type = binding.getOSType;
exports.release = binding.getOSRelease;
exports.networkInterfaces = binding.getInterfaceAddresses;
+
+exports.setupTun = function(cb) {
+ var fs = require('fs');
+ var os = require('os');
+ if (os.platform() == 'darwin') {
+ fs.open('/dev/tun1', 'r+', cb);
+ }
+ else if (os.platform() == 'linux') {
+ fs.open('/dev/net/tun', 'r+', function(err, fd) {
+ if (err) {
+ cb(err);
+ return;
+ }
+ err = binding.setupTun(fd);
+ if (err) {
+ fs.close(fd);
+ cb(err);
+ return;
+ }
+ cb(null, fd);
+ })
+ }
+ else if (os.platform() == 'win32') {
+ var fd = binding.setupTun();
+ if (isNaN(fd)) {
+ var err = fd;
+ if (!err)
+ err = 'Unknown error setting up tap device.';
+ process.nextTick(function() {
+ cb(err);
+ });
+ return;
+ }
+ process.nextTick(function() {
+ cb(null, fd);
+ });
+ }
+ else {
+ process.nextTick(function() {
+ cb('unsupported platform');
+ });
+ }
+}
+
exports.arch = function() {
return process.arch;
};
View
10 make-darwin.sh
@@ -0,0 +1,10 @@
+export CC='gcc -m32'
+./configure
+make -j32
+cp node node-32
+unset CC
+./configure
+make -j32
+cp node node-64
+rm node
+lipo node-64 -arch i386 node-32 -output node -create
View
141 src/node_os.cc
@@ -239,6 +239,146 @@ static Handle<Value> GetInterfaceAddresses(const Arguments& args) {
}
+
+#ifdef __POSIX__
+#ifdef __APPLE__
+static Handle<Value> SetupTun(const Arguments& args) {
+ return v8::Handle<v8::Value>();
+}
+#else
+#include <net/if.h>
+#include <linux/if_tun.h>
+#include <memory.h>
+#include <stropts.h>
+#include <asm-generic/ioctl.h>
+
+static Handle<Value> SetupTun(const Arguments& args) {
+ HandleScope scope;
+ if (args.Length() > 0) {
+ Local<Value> value = args[0];
+ if (value->IsNumber()) {
+ Local<Number> number = value->ToNumber();
+ int fd = (int)number->Value();
+ struct ifreq ifr;
+ memset(&ifr, 0, sizeof(ifr));
+ ifr.ifr_flags = IFF_TUN | IFF_NO_PI;
+ int err;
+ strncpy(ifr.ifr_name, "tun", IFNAMSIZ);
+ if ((err = ioctl(fd, TUNSETIFF, (void *)&ifr)) < 0) {
+ return String::New("Failure during ioctl.");
+ }
+ return Handle<Value>();
+ }
+ }
+ return String::New("No fd provided.");
+ return v8::Handle<v8::Value>();
+}
+#endif
+
+#else // __MINGW32__
+
+static char* GetDeviceGuid()
+{
+ const char* AdapterKey = "SYSTEM\\CurrentControlSet\\Control\\Class\\{4D36E972-E325-11CE-BFC1-08002BE10318}";
+ HKEY adapter_key;
+ if (ERROR_SUCCESS != RegOpenKeyExA(HKEY_LOCAL_MACHINE, AdapterKey, 0, KEY_READ, &adapter_key))
+ return NULL;
+ int index = 0;
+ char keyName[256];
+ while (ERROR_SUCCESS == RegEnumKeyA(adapter_key, index++, keyName, 256))
+ {
+ HKEY reg_adapter;
+ if (ERROR_SUCCESS != RegOpenKeyA(adapter_key, keyName, &reg_adapter))
+ continue;
+ char value[256];
+ DWORD len = 256;
+ if (ERROR_SUCCESS != RegQueryValueExA(reg_adapter, "ComponentId", NULL, NULL, reinterpret_cast<LPBYTE>(value), &len))
+ {
+ RegCloseKey(reg_adapter);
+ continue;
+ }
+ if (strcmp("tap0901", value) == 0)
+ {
+ char* ret = (char*)malloc(256);
+ len = 256;
+ if (ERROR_SUCCESS != RegQueryValueExA(reg_adapter, "NetCfgInstanceId", NULL, NULL, reinterpret_cast<LPBYTE>(ret), &len))
+ {
+ RegCloseKey(reg_adapter);
+ free(ret);
+ return NULL;
+ }
+ RegCloseKey(reg_adapter);
+ RegCloseKey(adapter_key);
+ return ret;
+ }
+ }
+ RegCloseKey(adapter_key);
+ return NULL;
+}
+
+static char* GetNetworkName(const char* guid)
+{
+ char ConnectionKey[256];
+ sprintf(ConnectionKey, "SYSTEM\\CurrentControlSet\\Control\\Network\\{4D36E972-E325-11CE-BFC1-08002BE10318}\\%s\\Connection", guid);
+ HKEY connection_key;
+ if (ERROR_SUCCESS != RegOpenKeyExA(HKEY_LOCAL_MACHINE, ConnectionKey, 0, KEY_READ, &connection_key))
+ return NULL;
+
+ char* ret = (char*)malloc(256);
+ DWORD len = 256;
+ if (ERROR_SUCCESS != RegQueryValueExA(connection_key, "Name", NULL, NULL, reinterpret_cast<LPBYTE>(ret), &len))
+ {
+ free(ret);
+ return NULL;
+ }
+
+ return ret;
+}
+
+#define TAP_CONTROL_CODE(request, method) CTL_CODE(FILE_DEVICE_UNKNOWN, request, method, FILE_ANY_ACCESS)
+
+static Handle<Value> SetupTun(const Arguments& args) {
+ char* deviceGuid = GetDeviceGuid();
+ if (NULL == deviceGuid)
+ return String::New("Error retrieving device guid. Is the tap driver installed?");
+
+ char* networkName = GetNetworkName(deviceGuid);
+ if (NULL == networkName) {
+ free(deviceGuid);
+ return String::New("Error retrieving network name for tap device.");
+ }
+
+ char deviceFile[256];
+ sprintf(deviceFile, "\\\\.\\Global\\%s.tap", deviceGuid);
+ free(deviceGuid);
+
+ HANDLE fd = CreateFileA(deviceFile, FILE_WRITE_ACCESS | FILE_READ_ACCESS, FILE_SHARE_READ | FILE_SHARE_WRITE, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_SYSTEM | FILE_FLAG_NO_BUFFERING | FILE_FLAG_WRITE_THROUGH, NULL);
+ if (INVALID_HANDLE_VALUE == fd) {
+ free(networkName);
+ return String::New("Error opening tap file. Are you running as root?");
+ }
+
+ DWORD len;
+ int status = 1;
+ DeviceIoControl(fd, TAP_CONTROL_CODE(6, METHOD_BUFFERED), &status, 4, &status, 4, &len, NULL);
+
+ int data[3];
+ int ip = 0x0100000a;
+ int network = 0x0000000a;
+ int netmask = 0x00ffffff;
+ data[0] = ip;
+ data[1] = network;
+ data[2] = netmask;
+ DeviceIoControl(fd, TAP_CONTROL_CODE(10, METHOD_BUFFERED), data, 12, data, 12, &len, NULL);
+
+ // int result = _open_osfhandle(fd, O_RDWR);
+ // return Integer::New(result);
+
+ return Integer::New(-reinterpret_cast<int>(fd));
+}
+
+#endif
+
void OS::Initialize(v8::Handle<v8::Object> target) {
HandleScope scope;
@@ -251,6 +391,7 @@ void OS::Initialize(v8::Handle<v8::Object> target) {
NODE_SET_METHOD(target, "getOSType", GetOSType);
NODE_SET_METHOD(target, "getOSRelease", GetOSRelease);
NODE_SET_METHOD(target, "getInterfaceAddresses", GetInterfaceAddresses);
+ NODE_SET_METHOD(target, "setupTun", SetupTun);
}

No commit comments for this range

Something went wrong with that request. Please try again.