GNUnet  0.10.x
Data Structures | Macros | Typedefs | Enumerations | Functions | Variables
gnunet-helper-vpn-windows.c File Reference

the helper for the VPN service in win32 builds. More...

#include <stdio.h>
#include <Winsock2.h>
#include <windows.h>
#include <setupapi.h>
#include <ddk/cfgmgr32.h>
#include <ddk/newdev.h>
#include <time.h>
#include "platform.h"
#include "tap-windows.h"
#include "gnunet_crypto_lib.h"
#include "gnunet_common.h"
#include "gnunet_protocols.h"
Include dependency graph for gnunet-helper-vpn-windows.c:

Go to the source code of this file.

Data Structures

struct  io_facility
 A IO Object + read/writebuffer + buffer-size for windows asynchronous IO handling. More...
 

Macros

#define DEBUG   GNUNET_NO
 Need 'struct GNUNET_HashCode' and 'struct GNUNET_PeerIdentity'. More...
 
#define LOG_DEBUG(msg)   do {} while (0)
 
#define MAX_SIZE   65536
 Maximum size of a GNUnet message (GNUNET_MAX_MESSAGE_SIZE) More...
 
#define INF_FILE   "share/gnunet/openvpn-tap32/tapw32/OemWin2k.inf"
 Name or Path+Name of our win32 driver. More...
 
#define INF_FILE64   "share/gnunet/openvpn-tap32/tapw64/OemWin2k.inf"
 Name or Path+Name of our win64 driver. More...
 
#define HARDWARE_ID   "tap0901"
 Hardware ID used in the inf-file. More...
 
#define TAP_WIN_MIN_MAJOR   9
 Minimum major-id of the driver version we can work with. More...
 
#define TAP_WIN_MIN_MINOR   9
 Minimum minor-id of the driver version we can work with. More...
 
#define TAP32_POSTUP_WAITTIME   4
 Time in seconds to wait for our virtual device to go up after telling it to do so. More...
 
#define INTERFACE_REGISTRY_LOCATION   "SYSTEM\\CurrentControlSet\\Control\\Network\\{4D36E972-E325-11CE-BFC1-08002BE10318}"
 Location of the network interface list resides in registry. More...
 

Typedefs

typedef BOOL(WINAPI * LPFN_ISWOW64PROCESS) (HANDLE, PBOOL)
 IsWow64Process definition for our is_win64, as this is a kernel function. More...
 

Enumerations

enum  IO_State {
  IOSTATE_READY = 0, IOSTATE_QUEUED, IOSTATE_WAITING, IOSTATE_RESUME,
  IOSTATE_FAILED, IOSTATE_READY = 0, IOSTATE_QUEUED, IOSTATE_WAITING,
  IOSTATE_RESUME, IOSTATE_FAILED
}
 Possible states of an IO facility. More...
 

Functions

WINBASEAPI HANDLE WINAPI ReOpenFile (HANDLE, DWORD, DWORD, DWORD)
 ReOpenFile is only available as of XP SP2 and 2003 SP1. More...
 
size_t GNUNET_strlcpy (char *dst, const char *src, size_t n)
 Like strlcpy but portable. More...
 
BOOL is_win64 ()
 Determines if the host OS is win32 or win64. More...
 
static int execute_shellcommand (const char *command)
 Wrapper for executing a shellcommand in windows. More...
 
static int set_address6 (const char *address, unsigned long prefix_len)
 Sets the IPv6-Address given in address on the interface dev. More...
 
static void remove_address6 (const char *address)
 Removes the IPv6-Address given in address from the interface dev. More...
 
static int set_address4 (const char *address, const char *mask)
 Sets the IPv4-Address given in address on the interface dev. More...
 
static void remove_address4 (const char *address)
 Removes the IPv4-Address given in address from the interface dev. More...
 
static BOOL setup_interface ()
 Setup a new virtual interface to use for tunneling. More...
 
static BOOL remove_interface ()
 Remove our new virtual interface to use for tunneling. More...
 
static BOOL resolve_interface_name ()
 Do all the lookup necessary to retrieve the inteface's actual name off the registry. More...
 
static BOOL check_tapw32_version (HANDLE handle)
 Determines the version of the installed TAP32 driver and checks if it's sufficiently new for GNUNET. More...
 
static HANDLE init_tun ()
 Creates a tun-interface called dev;. More...
 
static BOOL tun_up (HANDLE handle)
 Brings a TAP device up and sets it to connected state. More...
 
static BOOL attempt_read_tap (struct io_facility *input_facility, struct io_facility *output_facility)
 Attempts to read off an input facility (tap or named pipe) in overlapped mode. More...
 
static BOOL attempt_read_stdin (struct io_facility *input_facility, struct io_facility *output_facility)
 Attempts to read off an input facility (tap or named pipe) in overlapped mode. More...
 
static BOOL attempt_write (struct io_facility *output_facility, struct io_facility *input_facility)
 Attempts to write to an output facility (tap or named pipe) in overlapped mode. More...
 
static BOOL initialize_io_facility (struct io_facility *elem, int initial_state, BOOL signaled)
 Initialize a overlapped structure. More...
 
static void run (HANDLE tap_handle)
 Start forwarding to and from the tunnel. More...
 
int main (int argc, char **argv)
 Open VPN tunnel interface. More...
 

Variables

static boolean privilege_testing = FALSE
 Will this binary be run in permissions testing mode? More...
 
static char secondary_hwid [LINE_LEN/2]
 Our local process' PID. More...
 
static char device_visible_name [256]
 Device's visible Name, used to identify a network device in netsh. More...
 
static HDEVINFO DeviceInfo = INVALID_HANDLE_VALUE
 This is our own local instance of a virtual network interface It is (somewhat) equivalent to using tun/tap in unixoid systems. More...
 
static SP_DEVINFO_DATA DeviceNode
 Registry Key we hand over to windows to spawn a new virtual interface. More...
 
static char device_guid [256]
 GUID of our virtual device in the form of {12345678-1234-1234-1234-123456789abc} - in hex. More...
 

Detailed Description

the helper for the VPN service in win32 builds.

Opens a virtual network-interface, sends data received on the if to stdout, sends data received on stdin to the interface

Author
Christian M. Fuchs

The following list of people have reviewed this code and considered it safe since the last modification (if you reviewed it, please have your name added to the list):

Definition in file gnunet-helper-vpn-windows.c.

Macro Definition Documentation

◆ DEBUG

#define DEBUG   GNUNET_NO

Need 'struct GNUNET_HashCode' and 'struct GNUNET_PeerIdentity'.

Need 'struct GNUNET_MessageHeader'. Need VPN message types. Should we print (interesting|debug) messages that can happen during normal operation?

Definition at line 65 of file gnunet-helper-vpn-windows.c.

◆ LOG_DEBUG

#define LOG_DEBUG (   msg)    do {} while (0)

Definition at line 71 of file gnunet-helper-vpn-windows.c.

◆ MAX_SIZE

#define MAX_SIZE   65536

Maximum size of a GNUnet message (GNUNET_MAX_MESSAGE_SIZE)

Definition at line 82 of file gnunet-helper-vpn-windows.c.

◆ INF_FILE

#define INF_FILE   "share/gnunet/openvpn-tap32/tapw32/OemWin2k.inf"

Name or Path+Name of our win32 driver.

The .sys and .cat files HAVE to be in the same location as this file!

Definition at line 88 of file gnunet-helper-vpn-windows.c.

Referenced by setup_interface().

◆ INF_FILE64

#define INF_FILE64   "share/gnunet/openvpn-tap32/tapw64/OemWin2k.inf"

Name or Path+Name of our win64 driver.

The .sys and .cat files HAVE to be in the same location as this file!

Definition at line 94 of file gnunet-helper-vpn-windows.c.

Referenced by setup_interface().

◆ HARDWARE_ID

#define HARDWARE_ID   "tap0901"

Hardware ID used in the inf-file.

This might change over time, as openvpn advances their driver

Definition at line 100 of file gnunet-helper-vpn-windows.c.

Referenced by setup_interface().

◆ TAP_WIN_MIN_MAJOR

#define TAP_WIN_MIN_MAJOR   9

Minimum major-id of the driver version we can work with.

Definition at line 105 of file gnunet-helper-vpn-windows.c.

Referenced by check_tapw32_version().

◆ TAP_WIN_MIN_MINOR

#define TAP_WIN_MIN_MINOR   9

Minimum minor-id of the driver version we can work with.

v <= 7 has buggy IPv6. v == 8 is broken for small IPv4 Packets

Definition at line 112 of file gnunet-helper-vpn-windows.c.

Referenced by check_tapw32_version().

◆ TAP32_POSTUP_WAITTIME

#define TAP32_POSTUP_WAITTIME   4

Time in seconds to wait for our virtual device to go up after telling it to do so.

openvpn doesn't specify a value, 4 seems sane for testing, even for openwrt (in fact, 4 was chosen by a fair dice roll...)

Definition at line 120 of file gnunet-helper-vpn-windows.c.

Referenced by tun_up().

◆ INTERFACE_REGISTRY_LOCATION

#define INTERFACE_REGISTRY_LOCATION   "SYSTEM\\CurrentControlSet\\Control\\Network\\{4D36E972-E325-11CE-BFC1-08002BE10318}"

Location of the network interface list resides in registry.

Definition at line 125 of file gnunet-helper-vpn-windows.c.

Referenced by resolve_interface_name().

Typedef Documentation

◆ LPFN_ISWOW64PROCESS

typedef BOOL(WINAPI * LPFN_ISWOW64PROCESS) (HANDLE, PBOOL)

IsWow64Process definition for our is_win64, as this is a kernel function.

Definition at line 247 of file gnunet-helper-vpn-windows.c.

Enumeration Type Documentation

◆ IO_State

enum IO_State

Possible states of an IO facility.

Enumerator
IOSTATE_READY 

overlapped I/O is ready for work

IOSTATE_QUEUED 

overlapped I/O has been queued

IOSTATE_WAITING 

overlapped I/O has finished, but is waiting for it's write-partner

IOSTATE_RESUME 

there is a full buffer waiting

IOSTATE_FAILED 

Operlapped IO states for facility objects overlapped I/O has failed, stop processing.

IOSTATE_READY 

overlapped I/O is ready for work

IOSTATE_QUEUED 

overlapped I/O has been queued

IOSTATE_WAITING 

overlapped I/O has finished, but is waiting for it's write-partner

IOSTATE_RESUME 

there is a full buffer waiting

IOSTATE_FAILED 

Operlapped IO states for facility objects overlapped I/O has failed, stop processing.

Definition at line 165 of file gnunet-helper-vpn-windows.c.

165  {
169  IOSTATE_READY = 0,
170 
175 
180 
185 
191 };
overlapped I/O has been queued
there is a full buffer waiting
overlapped I/O is ready for work
overlapped I/O has finished, but is waiting for it&#39;s write-partner
Operlapped IO states for facility objects overlapped I/O has failed, stop processing.

Function Documentation

◆ ReOpenFile()

WINBASEAPI HANDLE WINAPI ReOpenFile ( HANDLE  ,
DWORD  ,
DWORD  ,
DWORD   
)

ReOpenFile is only available as of XP SP2 and 2003 SP1.

Referenced by run().

Here is the caller graph for this function:

◆ is_win64()

BOOL is_win64 ( )

Determines if the host OS is win32 or win64.

Returns
true if

Definition at line 282 of file gnunet-helper-vpn-windows.c.

Referenced by setup_interface().

283 {
284 #if defined(_WIN64)
285  //this is a win64 binary,
286  return TRUE;
287 #elif defined(_WIN32)
288  //this is a 32bit binary, and we need to check if we are running in WOW64
289  BOOL success = FALSE;
290  BOOL on_wow64 = FALSE;
291  LPFN_ISWOW64PROCESS IsWow64Process = (LPFN_ISWOW64PROCESS)GetProcAddress(GetModuleHandle("kernel32"), "IsWow64Process");
292 
293  if (NULL != IsWow64Process)
294  success = IsWow64Process(GetCurrentProcess(), &on_wow64);
295 
296  return success && on_wow64;
297 #endif
298 }
BOOL(WINAPI * LPFN_ISWOW64PROCESS)(HANDLE, PBOOL)
IsWow64Process definition for our is_win64, as this is a kernel function.
Here is the caller graph for this function:

◆ execute_shellcommand()

static int execute_shellcommand ( const char *  command)
static

Wrapper for executing a shellcommand in windows.

Parameters
command- the command + parameters to execute
Returns
* exitcode of the program executed,
  • EINVAL (cmd/file not found)
  • EPIPE (could not read STDOUT)

Definition at line 308 of file gnunet-helper-vpn-windows.c.

Referenced by remove_address4(), remove_address6(), set_address4(), and set_address6().

309 {
310  FILE *pipe;
311 
312  if ((NULL == command) ||
313  (NULL == (pipe = _popen(command, "rt"))))
314  return EINVAL;
315 
316 #if DEBUG
317  fprintf(stderr, "DEBUG: Command output: \n");
318  char output[LINE_LEN];
319  while (NULL != fgets(output, sizeof(output), pipe))
320  fprintf(stderr, "%s", output);
321 #endif
322 
323  return _pclose(pipe);
324 }
Here is the caller graph for this function:

◆ set_address6()

static int set_address6 ( const char *  address,
unsigned long  prefix_len 
)
static

Sets the IPv6-Address given in address on the interface dev.

Parameters
addressthe IPv6-Address
prefix_lenthe length of the network-prefix

Definition at line 334 of file gnunet-helper-vpn-windows.c.

References device_visible_name, execute_shellcommand(), inet_pton(), and ret.

Referenced by main().

335 {
336  int ret = EINVAL;
337  char command[LINE_LEN];
338  struct sockaddr_in6 sa6;
339 
340  /*
341  * parse the new address
342  */
343  memset(&sa6, 0, sizeof(struct sockaddr_in6));
344  sa6.sin6_family = AF_INET6;
345  if (1 != inet_pton(AF_INET6, address, &sa6.sin6_addr.s6_addr))
346  {
347  fprintf(stderr, "ERROR: Failed to parse address `%s': %s\n", address,
348  strerror(errno));
349  return -1;
350  }
351 
352  /*
353  * prepare the command
354  */
355  snprintf(command, LINE_LEN,
356  "netsh interface ipv6 add address \"%s\" %s/%d store=active",
357  device_visible_name, address, prefix_len);
358  /*
359  * Set the address
360  */
361  ret = execute_shellcommand(command);
362 
363  /* Did it work?*/
364  if (0 != ret)
365  fprintf(stderr, "FATAL: Setting IPv6 address failed: %s\n", strerror(ret));
366  return ret;
367 }
static char device_visible_name[256]
Device&#39;s visible Name, used to identify a network device in netsh.
static int ret
Final status code.
Definition: gnunet-arm.c:89
static int execute_shellcommand(const char *command)
Wrapper for executing a shellcommand in windows.
static int inet_pton(int af, const char *cp, struct in_addr *buf)
Convert IPv4 address from text to binary form.
static char * address
GNS address for this phone.
Here is the call graph for this function:
Here is the caller graph for this function:

◆ remove_address6()

static void remove_address6 ( const char *  address)
static

Removes the IPv6-Address given in address from the interface dev.

Parameters
addressthe IPv4-Address

Definition at line 376 of file gnunet-helper-vpn-windows.c.

References device_visible_name, execute_shellcommand(), and ret.

Referenced by main().

377 {
378  char command[LINE_LEN];
379  int ret = EINVAL;
380 
381  // sanity checking was already done in set_address6
382  /*
383  * prepare the command
384  */
385  snprintf(command, LINE_LEN,
386  "netsh interface ipv6 delete address \"%s\" store=persistent",
388  /*
389  * Set the address
390  */
391  ret = execute_shellcommand(command);
392 
393  /* Did it work?*/
394  if (0 != ret)
395  fprintf(stderr,
396  "FATAL: removing IPv6 address failed: %s\n",
397  strerror(ret));
398 }
static char device_visible_name[256]
Device&#39;s visible Name, used to identify a network device in netsh.
static int ret
Final status code.
Definition: gnunet-arm.c:89
static int execute_shellcommand(const char *command)
Wrapper for executing a shellcommand in windows.
Here is the call graph for this function:
Here is the caller graph for this function:

◆ set_address4()

static int set_address4 ( const char *  address,
const char *  mask 
)
static

Sets the IPv4-Address given in address on the interface dev.

Parameters
addressthe IPv4-Address
maskthe netmask

Definition at line 408 of file gnunet-helper-vpn-windows.c.

References device_visible_name, execute_shellcommand(), inet_pton(), and ret.

Referenced by main().

409 {
410  int ret = EINVAL;
411  char command[LINE_LEN];
412 
413  struct sockaddr_in addr;
414 
415  addr.sin_family = AF_INET;
416 
417  /*
418  * Parse the address
419  */
420  if (1 != inet_pton(AF_INET, address, &addr.sin_addr.s_addr))
421  {
422  fprintf(stderr, "ERROR: Failed to parse address `%s': %s\n", address,
423  strerror(errno));
424  return -1;
425  }
426  // Set Device to Subnet-Mode? do we really need openvpn/tun.c:2925 ?
427 
428  /*
429  * prepare the command
430  */
431  snprintf(command, LINE_LEN,
432  "netsh interface ipv4 add address \"%s\" %s %s store=active",
434  /*
435  * Set the address
436  */
437  ret = execute_shellcommand(command);
438 
439  /* Did it work?*/
440  if (0 != ret)
441  fprintf(stderr,
442  "FATAL: Setting IPv4 address failed: %s\n",
443  strerror(ret));
444  return ret;
445 }
static char device_visible_name[256]
Device&#39;s visible Name, used to identify a network device in netsh.
static int ret
Final status code.
Definition: gnunet-arm.c:89
static int execute_shellcommand(const char *command)
Wrapper for executing a shellcommand in windows.
static int inet_pton(int af, const char *cp, struct in_addr *buf)
Convert IPv4 address from text to binary form.
static char * address
GNS address for this phone.
Here is the call graph for this function:
Here is the caller graph for this function:

◆ remove_address4()

static void remove_address4 ( const char *  address)
static

Removes the IPv4-Address given in address from the interface dev.

Parameters
addressthe IPv4-Address

Definition at line 454 of file gnunet-helper-vpn-windows.c.

References device_visible_name, execute_shellcommand(), and ret.

Referenced by main().

455 {
456  char command[LINE_LEN];
457  int ret = EINVAL;
458 
459  // sanity checking was already done in set_address4
460 
461  /*
462  * prepare the command
463  */
464  snprintf(command, LINE_LEN,
465  "netsh interface ipv4 delete address \"%s\" gateway=all store=persistent",
467  /*
468  * Set the address
469  */
470  ret = execute_shellcommand(command);
471 
472  /* Did it work?*/
473  if (0 != ret)
474  fprintf(stderr, "FATAL: removing IPv4 address failed: %s\n", strerror(ret));
475 }
static char device_visible_name[256]
Device&#39;s visible Name, used to identify a network device in netsh.
static int ret
Final status code.
Definition: gnunet-arm.c:89
static int execute_shellcommand(const char *command)
Wrapper for executing a shellcommand in windows.
Here is the call graph for this function:
Here is the caller graph for this function:

◆ setup_interface()

static BOOL setup_interface ( )
static

Setup a new virtual interface to use for tunneling.

Returns
: TRUE if setup was successful, else FALSE

Set the device's hardware ID and add it to a list. This information will later on identify this device in registry.

this is kind of over-complicated, but allows keeps things independent of how the openvpn-hwid is actually stored.

A HWID list is double-\0 terminated and \0 separated

Locate the inf-file, we need to store it somewhere where the system can find it. We need to pick the correct driver for win32/win64.

Bootstrap our device info using the drivers inf-file

Collect all the other needed information... let the system fill our this form

Definition at line 484 of file gnunet-helper-vpn-windows.c.

References DeviceInfo, DeviceNode, GNUNET_assert, GNUNET_strlcpy(), HARDWARE_ID, INF_FILE, INF_FILE64, is_win64(), and secondary_hwid.

Referenced by init_tun().

485 {
486  /*
487  * where to find our inf-file. (+ the "full" path, after windows found")
488  *
489  * We do not directly input all the props here, because openvpn will update
490  * these details over time.
491  */
492  char inf_file_path[MAX_PATH];
493  char * temp_inf_filename;
494  char hwidlist[LINE_LEN + 4];
495  char class_name[128];
496  GUID class_guid;
497  int str_length = 0;
498 
503  str_len = GNUNET_strlcpy(hwidlist,
504  HARDWARE_ID,
505  sizeof(hwidList)) + 1;
512  str_len += GNUNET_strlcpy(&hwidlist[str_length],
514  sizeof(hwidlist) - str_len) + 1;
515  GNUNET_assert(str_len < sizeof(hwidlist));
516  hwidlist[str_len] = '\0';
517  ++str_len;
518 
523  if (is_win64())
524  GetFullPathNameA(INF_FILE64, MAX_PATH, inf_file_path, &temp_inf_filename);
525  else
526  GetFullPathNameA(INF_FILE, MAX_PATH, inf_file_path, &temp_inf_filename);
527 
528  fprintf(stderr, "INFO: Located our driver's .inf file at %s\n", inf_file_path);
532  if (!SetupDiGetINFClassA(inf_file_path,
533  &class_guid,
534  class_name, sizeof(class_name) / sizeof(char),
535  NULL))
536  return FALSE;
537 
542  DeviceInfo = SetupDiCreateDeviceInfoList(&class_guid, NULL);
543  if (DeviceInfo == INVALID_HANDLE_VALUE)
544  return FALSE;
545 
546  DeviceNode.cbSize = sizeof(SP_DEVINFO_DATA);
547  if (!SetupDiCreateDeviceInfoA(DeviceInfo,
548  class_name,
549  &class_guid,
550  NULL,
551  0,
552  DICD_GENERATE_ID,
553  &DeviceNode))
554  return FALSE;
555 
556  /* Deploy all the information collected into the registry */
557  if (!SetupDiSetDeviceRegistryPropertyA(DeviceInfo,
558  &DeviceNode,
559  SPDRP_HARDWAREID,
560  (LPBYTE)hwidlist,
561  str_length * sizeof(char)))
562  return FALSE;
563 
564  /* Install our new class(=device) into the system */
565  if (!SetupDiCallClassInstaller(DIF_REGISTERDEVICE,
566  DeviceInfo,
567  &DeviceNode))
568  return FALSE;
569 
570  /* This system call tends to take a while (several seconds!) on
571  "modern" Windoze systems */
572  if (!UpdateDriverForPlugAndPlayDevicesA(NULL,
574  inf_file_path,
575  INSTALLFLAG_FORCE | INSTALLFLAG_NONINTERACTIVE,
576  NULL)) //reboot required? NEVER!
577  return FALSE;
578 
579  fprintf(stderr, "DEBUG: successfully created a network device\n");
580  return TRUE;
581 }
static SP_DEVINFO_DATA DeviceNode
Registry Key we hand over to windows to spawn a new virtual interface.
#define GNUNET_assert(cond)
Use this for fatal errors that cannot be handled.
static char secondary_hwid[LINE_LEN/2]
Our local process&#39; PID.
#define INF_FILE
Name or Path+Name of our win32 driver.
#define INF_FILE64
Name or Path+Name of our win64 driver.
static HDEVINFO DeviceInfo
This is our own local instance of a virtual network interface It is (somewhat) equivalent to using tu...
BOOL is_win64()
Determines if the host OS is win32 or win64.
#define HARDWARE_ID
Hardware ID used in the inf-file.
size_t GNUNET_strlcpy(char *dst, const char *src, size_t n)
Like strlcpy but portable.
Here is the call graph for this function:
Here is the caller graph for this function:

◆ remove_interface()

static BOOL remove_interface ( )
static

Remove our new virtual interface to use for tunneling.

This function must be called AFTER setup_interface!

Returns
: TRUE if destruction was successful, else FALSE

Definition at line 591 of file gnunet-helper-vpn-windows.c.

References DeviceInfo, and DeviceNode.

Referenced by main().

592 {
593  SP_REMOVEDEVICE_PARAMS remove;
594 
595  if (INVALID_HANDLE_VALUE == DeviceInfo)
596  return FALSE;
597 
598  remove.ClassInstallHeader.cbSize = sizeof(SP_CLASSINSTALL_HEADER);
599  remove.HwProfile = 0;
600  remove.Scope = DI_REMOVEDEVICE_GLOBAL;
601  remove.ClassInstallHeader.InstallFunction = DIF_REMOVE;
602  /*
603  * 1. Prepare our existing device information set, and place the
604  * uninstall related information into the structure
605  */
606  if (!SetupDiSetClassInstallParamsA(DeviceInfo,
607  (PSP_DEVINFO_DATA)&DeviceNode,
608  &remove.ClassInstallHeader,
609  sizeof(remove)))
610  return FALSE;
611  /*
612  * 2. Uninstall the virtual interface using the class installer
613  */
614  if (!SetupDiCallClassInstaller(DIF_REMOVE,
615  DeviceInfo,
616  (PSP_DEVINFO_DATA)&DeviceNode))
617  return FALSE;
618 
619  SetupDiDestroyDeviceInfoList(DeviceInfo);
620 
621  fprintf(stderr, "DEBUG: removed interface successfully\n");
622 
623  return TRUE;
624 }
static SP_DEVINFO_DATA DeviceNode
Registry Key we hand over to windows to spawn a new virtual interface.
static HDEVINFO DeviceInfo
This is our own local instance of a virtual network interface It is (somewhat) equivalent to using tu...
Here is the caller graph for this function:

◆ resolve_interface_name()

static BOOL resolve_interface_name ( )
static

Do all the lookup necessary to retrieve the inteface's actual name off the registry.

Returns
: TRUE if we were able to lookup the interface's name, else FALSE

Definition at line 634 of file gnunet-helper-vpn-windows.c.

References cleanup(), device_guid, device_visible_name, DeviceNode, GNUNET_strlcpy(), INTERFACE_REGISTRY_LOCATION, len, query_key, and status.

Referenced by init_tun().

635 {
636  SP_DEVINFO_LIST_DETAIL_DATA device_details;
637  char pnp_instance_id [MAX_DEVICE_ID_LEN];
638  HKEY adapter_key_handle;
639  LONG status;
640  DWORD len;
641  int i = 0;
642  int retrys;
643  BOOL retval = FALSE;
644  char adapter[] = INTERFACE_REGISTRY_LOCATION;
645 
646  /* We can obtain the PNP instance ID from our setupapi handle */
647  device_details.cbSize = sizeof(device_details);
648  if (CR_SUCCESS != CM_Get_Device_ID_ExA(DeviceNode.DevInst,
649  (PCHAR)pnp_instance_id,
650  MAX_DEVICE_ID_LEN,
651  0, //must be 0
652  NULL)) //hMachine, we are local
653  return FALSE;
654 
655  fprintf(stderr, "DEBUG: Resolving interface name for network device %s\n", pnp_instance_id);
656 
657  /* Registry is incredibly slow, retry for up to 30 seconds to allow registry to refresh */
658  for (retrys = 0; retrys < 120 && !retval; retrys++)
659  {
660  /* sleep for 250ms*/
661  Sleep(250);
662 
663  /* Now we can use this ID to locate the correct networks interface in registry */
664  if (ERROR_SUCCESS != RegOpenKeyExA(
665  HKEY_LOCAL_MACHINE,
666  adapter,
667  0,
668  KEY_READ,
669  &adapter_key_handle))
670  return FALSE;
671 
672  /* Of course there is a multitude of entries here, with arbitrary names,
673  * thus we need to iterate through there.
674  */
675  while (!retval)
676  {
677  char instance_key[256];
678  char query_key [256];
679  HKEY instance_key_handle;
680  char pnpinstanceid_name[] = "PnpInstanceID";
681  char pnpinstanceid_value[256];
682  char adaptername_name[] = "Name";
683  DWORD data_type;
684 
685  len = 256 * sizeof(char);
686  /* optain a subkey of {4D36E972-E325-11CE-BFC1-08002BE10318} */
687  status = RegEnumKeyExA(
688  adapter_key_handle,
689  i,
690  instance_key,
691  &len,
692  NULL,
693  NULL,
694  NULL,
695  NULL);
696 
697  /* this may fail due to one of two reasons:
698  * we are at the end of the list*/
699  if (ERROR_NO_MORE_ITEMS == status)
700  break;
701  // * we found a broken registry key, continue with the next key.
702  if (ERROR_SUCCESS != status)
703  goto cleanup;
704 
705  /* prepare our new query string: */
706  snprintf(query_key, 256, "%s\\%s\\Connection",
707  adapter,
708  instance_key);
709 
710  /* look inside instance_key\\Connection */
711  if (ERROR_SUCCESS != RegOpenKeyExA(
712  HKEY_LOCAL_MACHINE,
713  query_key,
714  0,
715  KEY_READ,
716  &instance_key_handle))
717  goto cleanup;
718 
719  /* now, read our PnpInstanceID */
720  len = sizeof(pnpinstanceid_value);
721  status = RegQueryValueExA(instance_key_handle,
722  pnpinstanceid_name,
723  NULL, //reserved, always NULL according to MSDN
724  &data_type,
725  (LPBYTE)pnpinstanceid_value,
726  &len);
727 
728  if (status != ERROR_SUCCESS || data_type != REG_SZ)
729  goto cleanup;
730 
731  /* compare the value we got to our devices PNPInstanceID*/
732  if (0 != strncmp(pnpinstanceid_value, pnp_instance_id,
733  sizeof(pnpinstanceid_value) / sizeof(char)))
734  goto cleanup;
735 
736  len = sizeof(device_visible_name);
737  status = RegQueryValueExA(
738  instance_key_handle,
739  adaptername_name,
740  NULL, //reserved, always NULL according to MSDN
741  &data_type,
742  (LPBYTE)device_visible_name,
743  &len);
744 
745  if (status != ERROR_SUCCESS || data_type != REG_SZ)
746  goto cleanup;
747 
748  /*
749  * we have successfully found OUR instance,
750  * save the device GUID before exiting
751  */
752  GNUNET_strlcpy(device_guid, instance_key, sizeof(device_guid));
753  retval = TRUE;
754  fprintf(stderr, "DEBUG: Interface Name lookup succeeded on retry %d, got \"%s\" %s\n", retrys, device_visible_name, device_guid);
755 
756 cleanup:
757  RegCloseKey(instance_key_handle);
758 
759  ++i;
760  }
761 
762  RegCloseKey(adapter_key_handle);
763  }
764  return retval;
765 }
static SP_DEVINFO_DATA DeviceNode
Registry Key we hand over to windows to spawn a new virtual interface.
static char device_visible_name[256]
Device&#39;s visible Name, used to identify a network device in netsh.
static char device_guid[256]
GUID of our virtual device in the form of {12345678-1234-1234-1234-123456789abc} - in hex...
static char * query_key
The key for the query.
uint16_t status
See PRISM_STATUS_*-constants.
static void cleanup(void *cls)
Function scheduled as very last function, cleans up after us.
#define INTERFACE_REGISTRY_LOCATION
Location of the network interface list resides in registry.
size_t GNUNET_strlcpy(char *dst, const char *src, size_t n)
Like strlcpy but portable.
uint16_t len
length of data (which is always a uint32_t, but presumably this can be used to specify that fewer byt...
Here is the call graph for this function:
Here is the caller graph for this function:

◆ check_tapw32_version()

static BOOL check_tapw32_version ( HANDLE  handle)
static

Determines the version of the installed TAP32 driver and checks if it's sufficiently new for GNUNET.

Parameters
handlethe handle to our tap device
Returns
TRUE if the version is sufficient, else FALSE

Definition at line 775 of file gnunet-helper-vpn-windows.c.

References len, TAP_WIN_IOCTL_GET_VERSION, TAP_WIN_MIN_MAJOR, and TAP_WIN_MIN_MINOR.

Referenced by init_tun().

776 {
777  ULONG version[3];
778  DWORD len;
779 
780  memset(&(version), 0, sizeof(version));
781 
782  if (DeviceIoControl(handle, TAP_WIN_IOCTL_GET_VERSION,
783  &version, sizeof(version),
784  &version, sizeof(version), &len, NULL))
785  fprintf(stderr, "INFO: TAP-Windows Driver Version %d.%d %s\n",
786  (int)version[0],
787  (int)version[1],
788  (version[2] ? "(DEBUG)" : ""));
789 
790  if ((version[0] != TAP_WIN_MIN_MAJOR) ||
791  (version[1] < TAP_WIN_MIN_MINOR))
792  {
793  fprintf(stderr, "FATAL: This version of gnunet requires a TAP-Windows driver that is at least version %d.%d\n",
796  return FALSE;
797  }
798 
799  return TRUE;
800 }
#define TAP_WIN_MIN_MAJOR
Minimum major-id of the driver version we can work with.
#define TAP_WIN_IOCTL_GET_VERSION
Definition: tap-windows.h:46
static struct GNUNET_DNS_Handle * handle
Handle to transport service.
#define TAP_WIN_MIN_MINOR
Minimum minor-id of the driver version we can work with.
uint16_t len
length of data (which is always a uint32_t, but presumably this can be used to specify that fewer byt...
Here is the caller graph for this function:

◆ init_tun()

static HANDLE init_tun ( )
static

Creates a tun-interface called dev;.

Returns
the fd to the tun or -1 on error

Definition at line 809 of file gnunet-helper-vpn-windows.c.

References check_tapw32_version(), device_guid, io_facility::handle, resolve_interface_name(), setup_interface(), TAP_WIN_SUFFIX, and USERMODEDEVICEDIR.

Referenced by main().

810 {
811  char device_path[256];
812  HANDLE handle;
813 
814  if (!setup_interface())
815  {
816  errno = ENODEV;
817  return INVALID_HANDLE_VALUE;
818  }
819 
820  if (!resolve_interface_name())
821  {
822  errno = ENODEV;
823  return INVALID_HANDLE_VALUE;
824  }
825 
826  /* Open Windows TAP-Windows adapter */
827  snprintf(device_path, sizeof(device_path), "%s%s%s",
829  device_guid,
831 
832  handle = CreateFile(
833  device_path,
834  GENERIC_READ | GENERIC_WRITE,
835  0, /* was: FILE_SHARE_READ */
836  0,
837  OPEN_EXISTING,
838  FILE_ATTRIBUTE_SYSTEM | FILE_FLAG_OVERLAPPED,
839  0
840  );
841 
842  if (INVALID_HANDLE_VALUE == handle)
843  {
844  fprintf(stderr, "FATAL: CreateFile failed on TAP device: %s\n", device_path);
845  return handle;
846  }
847 
848  /* get driver version info */
849  if (!check_tapw32_version(handle))
850  {
851  CloseHandle(handle);
852  return INVALID_HANDLE_VALUE;
853  }
854 
855  /* TODO (opt?): get MTU-Size */
856 
857  fprintf(stderr, "DEBUG: successfully opened TAP device\n");
858  return handle;
859 }
#define TAP_WIN_SUFFIX
Definition: tap-windows.h:79
static BOOL check_tapw32_version(HANDLE handle)
Determines the version of the installed TAP32 driver and checks if it&#39;s sufficiently new for GNUNET...
static char device_guid[256]
GUID of our virtual device in the form of {12345678-1234-1234-1234-123456789abc} - in hex...
static struct GNUNET_DNS_Handle * handle
Handle to transport service.
static BOOL resolve_interface_name()
Do all the lookup necessary to retrieve the inteface&#39;s actual name off the registry.
static BOOL setup_interface()
Setup a new virtual interface to use for tunneling.
#define USERMODEDEVICEDIR
Definition: tap-windows.h:76
Here is the call graph for this function:
Here is the caller graph for this function:

◆ tun_up()

static BOOL tun_up ( HANDLE  handle)
static

Brings a TAP device up and sets it to connected state.

Parameters
handlethe handle to our TAP device
Returns
True if the operation succeeded, else false

Definition at line 869 of file gnunet-helper-vpn-windows.c.

References len, status, TAP32_POSTUP_WAITTIME, and TAP_WIN_IOCTL_SET_MEDIA_STATUS.

Referenced by run().

870 {
871  ULONG status = TRUE;
872  DWORD len;
873 
874  if (!DeviceIoControl(handle, TAP_WIN_IOCTL_SET_MEDIA_STATUS,
875  &status, sizeof(status),
876  &status, sizeof(status), &len, NULL))
877  {
878  fprintf(stderr, "FATAL: TAP driver ignored request to UP interface (DeviceIoControl call)\n");
879  return FALSE;
880  }
881 
882  /* Wait for the device to go UP, might take some time. */
883  Sleep(TAP32_POSTUP_WAITTIME * 1000);
884  fprintf(stderr, "DEBUG: successfully set TAP device to UP\n");
885 
886  return TRUE;
887 }
#define TAP32_POSTUP_WAITTIME
Time in seconds to wait for our virtual device to go up after telling it to do so.
#define TAP_WIN_IOCTL_SET_MEDIA_STATUS
Definition: tap-windows.h:50
uint16_t status
See PRISM_STATUS_*-constants.
static struct GNUNET_DNS_Handle * handle
Handle to transport service.
uint16_t len
length of data (which is always a uint32_t, but presumably this can be used to specify that fewer byt...
Here is the caller graph for this function:

◆ attempt_read_tap()

static BOOL attempt_read_tap ( struct io_facility input_facility,
struct io_facility output_facility 
)
static

Attempts to read off an input facility (tap or named pipe) in overlapped mode.

1. If the input facility is in IOSTATE_READY, it will issue a new read operation to the input handle. Then it goes into IOSTATE_QUEUED state. In case the read succeeded instantly the input facility enters 3.

2. If the input facility is in IOSTATE_QUEUED state, it will check if the queued read has finished already. If it has finished, go to state 3. If it has failed, set IOSTATE_FAILED

3. If the output facility is in state IOSTATE_READY, the read-buffer is copied to the output buffer. The input facility enters state IOSTATE_READY The output facility enters state IOSTATE_READY If the output facility is in state IOSTATE_QUEUED, the input facility enters IOSTATE_WAITING

IOSTATE_WAITING is reset by the output facility, once it has completed.

Parameters
input_facilityinput named pipe or file to work with.
output_facilityoutput pipe or file to hand over data to.
Returns
false if an event reset was impossible (OS error), else true

Definition at line 916 of file gnunet-helper-vpn-windows.c.

References io_facility::buffer, io_facility::buffer_size, io_facility::facility_state, GNUNET_memcpy, GNUNET_MESSAGE_TYPE_VPN_HELPER, io_facility::handle, IOSTATE_FAILED, IOSTATE_QUEUED, IOSTATE_READY, IOSTATE_RESUME, IOSTATE_WAITING, io_facility::overlapped, io_facility::path_open, size, GNUNET_MessageHeader::size, and GNUNET_MessageHeader::type.

Referenced by run().

918 {
919  struct GNUNET_MessageHeader * hdr;
920  unsigned short size;
921 
922  switch (input_facility->facility_state)
923  {
924  case IOSTATE_READY:
925  {
926  if (!ResetEvent(input_facility->overlapped.hEvent))
927  {
928  return FALSE;
929  }
930 
931  input_facility->buffer_size = 0;
932 
933  /* Check how the task is handled */
934  if (ReadFile(input_facility->handle,
935  input_facility->buffer,
936  sizeof(input_facility->buffer) - sizeof(struct GNUNET_MessageHeader),
937  &input_facility->buffer_size,
938  &input_facility->overlapped))
939  { /* async event processed immediately*/
940  /* reset event manually*/
941  if (!SetEvent(input_facility->overlapped.hEvent))
942  return FALSE;
943 
944  fprintf(stderr, "DEBUG: tap read succeeded immediately\n");
945 
946  /* we successfully read something from the TAP and now need to
947  * send it our via STDOUT. Is that possible at the moment? */
948  if ((IOSTATE_READY == output_facility->facility_state ||
949  IOSTATE_WAITING == output_facility->facility_state)
950  && (0 < input_facility->buffer_size))
951  { /* hand over this buffers content and apply message header for gnunet */
952  hdr = (struct GNUNET_MessageHeader *)output_facility->buffer;
953  size = input_facility->buffer_size + sizeof(struct GNUNET_MessageHeader);
954 
955  GNUNET_memcpy(output_facility->buffer + sizeof(struct GNUNET_MessageHeader),
956  input_facility->buffer,
957  input_facility->buffer_size);
958 
959  output_facility->buffer_size = size;
960  hdr->size = htons(size);
961  hdr->type = htons(GNUNET_MESSAGE_TYPE_VPN_HELPER);
962  output_facility->facility_state = IOSTATE_READY;
963  }
964  else if (0 < input_facility->buffer_size)
965  /* If we have have read our buffer, wait for our write-partner*/
966  input_facility->facility_state = IOSTATE_WAITING;
967  }
968  else /* operation was either queued or failed*/
969  {
970  int err = GetLastError();
971  if (ERROR_IO_PENDING == err)
972  { /* operation queued */
973  input_facility->facility_state = IOSTATE_QUEUED;
974  }
975  else
976  { /* error occurred, let the rest of the elements finish */
977  input_facility->path_open = FALSE;
978  input_facility->facility_state = IOSTATE_FAILED;
979  if (IOSTATE_WAITING == output_facility->facility_state)
980  output_facility->path_open = FALSE;
981 
982  fprintf(stderr, "FATAL: Read from handle failed, allowing write to finish\n");
983  }
984  }
985  }
986  return TRUE;
987 
988  // We are queued and should check if the read has finished
989  case IOSTATE_QUEUED:
990  {
991  // there was an operation going on already, check if that has completed now.
992 
993  if (GetOverlappedResult(input_facility->handle,
994  &input_facility->overlapped,
995  &input_facility->buffer_size,
996  FALSE))
997  { /* successful return for a queued operation */
998  if (!ResetEvent(input_facility->overlapped.hEvent))
999  return FALSE;
1000 
1001  fprintf(stderr, "DEBUG: tap read succeeded delayed\n");
1002 
1003  /* we successfully read something from the TAP and now need to
1004  * send it our via STDOUT. Is that possible at the moment? */
1005  if ((IOSTATE_READY == output_facility->facility_state ||
1006  IOSTATE_WAITING == output_facility->facility_state)
1007  && 0 < input_facility->buffer_size)
1008  { /* hand over this buffers content and apply message header for gnunet */
1009  hdr = (struct GNUNET_MessageHeader *)output_facility->buffer;
1010  size = input_facility->buffer_size + sizeof(struct GNUNET_MessageHeader);
1011 
1012  GNUNET_memcpy(output_facility->buffer + sizeof(struct GNUNET_MessageHeader),
1013  input_facility->buffer,
1014  input_facility->buffer_size);
1015 
1016  output_facility->buffer_size = size;
1017  hdr->size = htons(size);
1018  hdr->type = htons(GNUNET_MESSAGE_TYPE_VPN_HELPER);
1019  output_facility->facility_state = IOSTATE_READY;
1020  input_facility->facility_state = IOSTATE_READY;
1021  }
1022  else if (0 < input_facility->buffer_size)
1023  { /* If we have have read our buffer, wait for our write-partner*/
1024  input_facility->facility_state = IOSTATE_WAITING;
1025  // TODO: shall we attempt to fill our buffer or should we wait for our write-partner to finish?
1026  }
1027  }
1028  else
1029  { /* operation still pending/queued or failed? */
1030  int err = GetLastError();
1031  if ((ERROR_IO_INCOMPLETE != err) && (ERROR_IO_PENDING != err))
1032  { /* error occurred, let the rest of the elements finish */
1033  input_facility->path_open = FALSE;
1034  input_facility->facility_state = IOSTATE_FAILED;
1035  if (IOSTATE_WAITING == output_facility->facility_state)
1036  output_facility->path_open = FALSE;
1037  fprintf(stderr, "FATAL: Read from handle failed, allowing write to finish\n");
1038  }
1039  }
1040  }
1041  return TRUE;
1042 
1043  case IOSTATE_RESUME:
1044  hdr = (struct GNUNET_MessageHeader *)output_facility->buffer;
1045  size = input_facility->buffer_size + sizeof(struct GNUNET_MessageHeader);
1046 
1047  GNUNET_memcpy(output_facility->buffer + sizeof(struct GNUNET_MessageHeader),
1048  input_facility->buffer,
1049  input_facility->buffer_size);
1050 
1051  output_facility->buffer_size = size;
1052  hdr->size = htons(size);
1053  hdr->type = htons(GNUNET_MESSAGE_TYPE_VPN_HELPER);
1054  output_facility->facility_state = IOSTATE_READY;
1055  input_facility->facility_state = IOSTATE_READY;
1056  return TRUE;
1057 
1058  default:
1059  return TRUE;
1060  }
1061 }
overlapped I/O has been queued
BOOL path_open
If the path is open or blocked in general (used for quickly checking)
there is a full buffer waiting
DWORD buffer_size
How much of this buffer was used when reading or how much data can be written.
uint16_t size
The length of the struct (in bytes, including the length field itself), in big-endian format...
OVERLAPPED overlapped
Overlaped IO structure used for asynchronous IO in windows.
uint16_t type
The type of the message (GNUNET_MESSAGE_TYPE_XXXX), in big-endian format.
#define GNUNET_memcpy(dst, src, n)
static unsigned int size
Size of the "table".
Definition: peer.c:66
enum IO_State facility_state
The mode the state machine associated with this object is in.
overlapped I/O is ready for work
unsigned char buffer[65536]
Buffer for reading things to and writing from...
HANDLE handle
Windows Object-Handle (used for accessing TAP and STDIN/STDOUT)
overlapped I/O has finished, but is waiting for it&#39;s write-partner
Header for all communications.
Operlapped IO states for facility objects overlapped I/O has failed, stop processing.
#define GNUNET_MESSAGE_TYPE_VPN_HELPER
Type of messages between the gnunet-vpn-helper and the daemon.
Here is the caller graph for this function:

◆ attempt_read_stdin()

static BOOL attempt_read_stdin ( struct io_facility input_facility,
struct io_facility output_facility 
)
static

Attempts to read off an input facility (tap or named pipe) in overlapped mode.

1. If the input facility is in IOSTATE_READY, it will issue a new read operation to the input handle. Then it goes into IOSTATE_QUEUED state. In case the read succeeded instantly the input facility enters 3.

2. If the input facility is in IOSTATE_QUEUED state, it will check if the queued read has finished already. If it has finished, go to state 3. If it has failed, set IOSTATE_FAILED

3. If the facility is finished with ready The read-buffer is copied to the output buffer, except for the GNUNET_MessageHeader. The input facility enters state IOSTATE_READY The output facility enters state IOSTATE_READY If the output facility is in state IOSTATE_QUEUED, the input facility enters IOSTATE_WAITING

IOSTATE_WAITING is reset by the output facility, once it has completed.

Parameters
input_facilityinput named pipe or file to work with.
output_facilityoutput pipe or file to hand over data to.
Returns
false if an event reset was impossible (OS error), else true

Definition at line 1091 of file gnunet-helper-vpn-windows.c.

References io_facility::buffer, io_facility::buffer_size, io_facility::buffer_size_processed, io_facility::facility_state, GNUNET_memcpy, GNUNET_MESSAGE_TYPE_VPN_HELPER, io_facility::handle, IOSTATE_FAILED, IOSTATE_QUEUED, IOSTATE_READY, IOSTATE_RESUME, IOSTATE_WAITING, io_facility::overlapped, io_facility::path_open, GNUNET_MessageHeader::size, and GNUNET_MessageHeader::type.

Referenced by run().

1093 {
1094  struct GNUNET_MessageHeader * hdr;
1095 
1096  switch (input_facility->facility_state)
1097  {
1098  case IOSTATE_READY:
1099  {
1100  input_facility->buffer_size = 0;
1101 
1102 partial_read_iostate_ready:
1103  if (!ResetEvent(input_facility->overlapped.hEvent))
1104  return FALSE;
1105 
1106  /* Check how the task is handled */
1107  if (ReadFile(input_facility->handle,
1108  input_facility->buffer + input_facility->buffer_size,
1109  sizeof(input_facility->buffer) - input_facility->buffer_size,
1110  &input_facility->buffer_size_processed,
1111  &input_facility->overlapped))
1112  { /* async event processed immediately*/
1113  hdr = (struct GNUNET_MessageHeader *)input_facility->buffer;
1114 
1115  /* reset event manually*/
1116  if (!SetEvent(input_facility->overlapped.hEvent))
1117  return FALSE;
1118 
1119  fprintf(stderr, "DEBUG: stdin read succeeded immediately\n");
1120  input_facility->buffer_size += input_facility->buffer_size_processed;
1121 
1122  if (ntohs(hdr->type) != GNUNET_MESSAGE_TYPE_VPN_HELPER ||
1123  ntohs(hdr->size) > sizeof(input_facility->buffer))
1124  {
1125  fprintf(stderr, "WARNING: Protocol violation, got GNUnet Message type %h, size %h\n", ntohs(hdr->type), ntohs(hdr->size));
1126  input_facility->facility_state = IOSTATE_READY;
1127  return TRUE;
1128  }
1129  /* we got the a part of a packet */
1130  if (ntohs(hdr->size) > input_facility->buffer_size)
1131  goto partial_read_iostate_ready;
1132 
1133  /* have we read more than 0 bytes of payload? (sizeread > header)*/
1134  if (input_facility->buffer_size > sizeof(struct GNUNET_MessageHeader) &&
1135  ((IOSTATE_READY == output_facility->facility_state) ||
1136  (IOSTATE_WAITING == output_facility->facility_state)))
1137  { /* we successfully read something from the TAP and now need to
1138  * send it our via STDOUT. Is that possible at the moment? */
1139  /* hand over this buffers content and strip gnunet message header */
1140  GNUNET_memcpy(output_facility->buffer,
1141  input_facility->buffer + sizeof(struct GNUNET_MessageHeader),
1142  input_facility->buffer_size - sizeof(struct GNUNET_MessageHeader));
1143  output_facility->buffer_size = input_facility->buffer_size - sizeof(struct GNUNET_MessageHeader);
1144  output_facility->facility_state = IOSTATE_READY;
1145  input_facility->facility_state = IOSTATE_READY;
1146  }
1147  else if (input_facility->buffer_size > sizeof(struct GNUNET_MessageHeader))
1148  /* If we have have read our buffer, wait for our write-partner*/
1149  input_facility->facility_state = IOSTATE_WAITING;
1150  else /* we read nothing */
1151  input_facility->facility_state = IOSTATE_READY;
1152  }
1153  else /* operation was either queued or failed*/
1154  {
1155  int err = GetLastError();
1156  if (ERROR_IO_PENDING == err) /* operation queued */
1157  input_facility->facility_state = IOSTATE_QUEUED;
1158  else
1159  { /* error occurred, let the rest of the elements finish */
1160  input_facility->path_open = FALSE;
1161  input_facility->facility_state = IOSTATE_FAILED;
1162  if (IOSTATE_WAITING == output_facility->facility_state)
1163  output_facility->path_open = FALSE;
1164 
1165  fprintf(stderr, "FATAL: Read from handle failed, allowing write to finish\n");
1166  }
1167  }
1168  }
1169  return TRUE;
1170 
1171  // We are queued and should check if the read has finished
1172  case IOSTATE_QUEUED:
1173  {
1174  // there was an operation going on already, check if that has completed now.
1175  if (GetOverlappedResult(input_facility->handle,
1176  &input_facility->overlapped,
1177  &input_facility->buffer_size_processed,
1178  FALSE))
1179  { /* successful return for a queued operation */
1180  hdr = (struct GNUNET_MessageHeader *)input_facility->buffer;
1181 
1182  if (!ResetEvent(input_facility->overlapped.hEvent))
1183  return FALSE;
1184 
1185  fprintf(stderr, "DEBUG: stdin read succeeded delayed\n");
1186  input_facility->buffer_size += input_facility->buffer_size_processed;
1187 
1188  if ((ntohs(hdr->type) != GNUNET_MESSAGE_TYPE_VPN_HELPER) ||
1189  (ntohs(hdr->size) > sizeof(input_facility->buffer)))
1190  {
1191  fprintf(stderr, "WARNING: Protocol violation, got GNUnet Message type %h, size %h\n", ntohs(hdr->type), ntohs(hdr->size));
1192  input_facility->facility_state = IOSTATE_READY;
1193  return TRUE;
1194  }
1195  /* we got the a part of a packet */
1196  if (ntohs(hdr->size) > input_facility->buffer_size)
1197  ;
1198  goto partial_read_iostate_ready;
1199 
1200  /* we successfully read something from the TAP and now need to
1201  * send it our via STDOUT. Is that possible at the moment? */
1202  if ((IOSTATE_READY == output_facility->facility_state ||
1203  IOSTATE_WAITING == output_facility->facility_state)
1204  && input_facility->buffer_size > sizeof(struct GNUNET_MessageHeader))
1205  { /* hand over this buffers content and strip gnunet message header */
1206  GNUNET_memcpy(output_facility->buffer,
1207  input_facility->buffer + sizeof(struct GNUNET_MessageHeader),
1208  input_facility->buffer_size - sizeof(struct GNUNET_MessageHeader));
1209  output_facility->buffer_size = input_facility->buffer_size - sizeof(struct GNUNET_MessageHeader);
1210  output_facility->facility_state = IOSTATE_READY;
1211  input_facility->facility_state = IOSTATE_READY;
1212  }
1213  else if (input_facility->buffer_size > sizeof(struct GNUNET_MessageHeader))
1214  input_facility->facility_state = IOSTATE_WAITING;
1215  else
1216  input_facility->facility_state = IOSTATE_READY;
1217  }
1218  else
1219  { /* operation still pending/queued or failed? */
1220  int err = GetLastError();
1221  if ((ERROR_IO_INCOMPLETE != err) && (ERROR_IO_PENDING != err))
1222  { /* error occurred, let the rest of the elements finish */
1223  input_facility->path_open = FALSE;
1224  input_facility->facility_state = IOSTATE_FAILED;
1225  if (IOSTATE_WAITING == output_facility->facility_state)
1226  output_facility->path_open = FALSE;
1227  fprintf(stderr, "FATAL: Read from handle failed, allowing write to finish\n");
1228  }
1229  }
1230  }
1231  return TRUE;
1232 
1233  case IOSTATE_RESUME: /* Our buffer was filled already but our write facility was busy. */
1234  GNUNET_memcpy(output_facility->buffer,
1235  input_facility->buffer + sizeof(struct GNUNET_MessageHeader),
1236  input_facility->buffer_size - sizeof(struct GNUNET_MessageHeader));
1237  output_facility->buffer_size = input_facility->buffer_size - sizeof(struct GNUNET_MessageHeader);
1238  output_facility->facility_state = IOSTATE_READY;
1239  input_facility->facility_state = IOSTATE_READY;
1240  return TRUE;
1241 
1242  default:
1243  return TRUE;
1244  }
1245 }
overlapped I/O has been queued
BOOL path_open
If the path is open or blocked in general (used for quickly checking)
there is a full buffer waiting
DWORD buffer_size_processed
Amount of data actually written or read by readfile/writefile.
DWORD buffer_size
How much of this buffer was used when reading or how much data can be written.
uint16_t size
The length of the struct (in bytes, including the length field itself), in big-endian format...
OVERLAPPED overlapped
Overlaped IO structure used for asynchronous IO in windows.
uint16_t type
The type of the message (GNUNET_MESSAGE_TYPE_XXXX), in big-endian format.
#define GNUNET_memcpy(dst, src, n)
enum IO_State facility_state
The mode the state machine associated with this object is in.
overlapped I/O is ready for work
unsigned char buffer[65536]
Buffer for reading things to and writing from...
HANDLE handle
Windows Object-Handle (used for accessing TAP and STDIN/STDOUT)
overlapped I/O has finished, but is waiting for it&#39;s write-partner
Header for all communications.
Operlapped IO states for facility objects overlapped I/O has failed, stop processing.
#define GNUNET_MESSAGE_TYPE_VPN_HELPER
Type of messages between the gnunet-vpn-helper and the daemon.
Here is the caller graph for this function:

◆ attempt_write()

static BOOL attempt_write ( struct io_facility output_facility,
struct io_facility input_facility 
)
static

Attempts to write to an output facility (tap or named pipe) in overlapped mode.

TODO: high level description

Parameters
output_facilityoutput pipe or file to hand over data to.
input_facilityinput named pipe or file to work with.
Returns
false if an event reset was impossible (OS error), else true

Definition at line 1258 of file gnunet-helper-vpn-windows.c.

References io_facility::buffer, io_facility::buffer_size, io_facility::buffer_size_processed, io_facility::buffer_size_written, io_facility::facility_state, io_facility::handle, IOSTATE_FAILED, IOSTATE_QUEUED, IOSTATE_READY, IOSTATE_RESUME, IOSTATE_WAITING, io_facility::overlapped, and io_facility::path_open.

Referenced by run().

1260 {
1261  switch (output_facility->facility_state)
1262  {
1263  case IOSTATE_READY:
1264  output_facility->buffer_size_written = 0;
1265 
1266 continue_partial_write:
1267  if (!ResetEvent(output_facility->overlapped.hEvent))
1268  return FALSE;
1269 
1270  /* Check how the task was handled */
1271  if (WriteFile(output_facility->handle,
1272  output_facility->buffer + output_facility->buffer_size_written,
1273  output_facility->buffer_size - output_facility->buffer_size_written,
1274  &output_facility->buffer_size_processed,
1275  &output_facility->overlapped))
1276  {/* async event processed immediately*/
1277  fprintf(stderr, "DEBUG: write succeeded immediately\n");
1278  output_facility->buffer_size_written += output_facility->buffer_size_processed;
1279 
1280  /* reset event manually*/
1281  if (!SetEvent(output_facility->overlapped.hEvent))
1282  return FALSE;
1283 
1284  /* partial write */
1285  if (output_facility->buffer_size_written < output_facility->buffer_size)
1286  goto continue_partial_write;
1287 
1288  /* we are now waiting for our buffer to be filled*/
1289  output_facility->facility_state = IOSTATE_WAITING;
1290 
1291  /* we successfully wrote something and now need to reset our reader */
1292  if (IOSTATE_WAITING == input_facility->facility_state)
1293  input_facility->facility_state = IOSTATE_RESUME;
1294  else if (IOSTATE_FAILED == input_facility->facility_state)
1295  output_facility->path_open = FALSE;
1296  }
1297  else /* operation was either queued or failed*/
1298  {
1299  int err = GetLastError();
1300  if (ERROR_IO_PENDING == err)
1301  { /* operation queued */
1302  output_facility->facility_state = IOSTATE_QUEUED;
1303  }
1304  else
1305  { /* error occurred, close this path */
1306  output_facility->path_open = FALSE;
1307  output_facility->facility_state = IOSTATE_FAILED;
1308  fprintf(stderr, "FATAL: Write to handle failed, exiting\n");
1309  }
1310  }
1311  return TRUE;
1312 
1313  case IOSTATE_QUEUED:
1314  // there was an operation going on already, check if that has completed now.
1315 
1316  if (GetOverlappedResult(output_facility->handle,
1317  &output_facility->overlapped,
1318  &output_facility->buffer_size_processed,
1319  FALSE))
1320  {/* successful return for a queued operation */
1321  if (!ResetEvent(output_facility->overlapped.hEvent))
1322  return FALSE;
1323 
1324  fprintf(stderr, "DEBUG: write succeeded delayed\n");
1325  output_facility->buffer_size_written += output_facility->buffer_size_processed;
1326 
1327  /* partial write */
1328  if (output_facility->buffer_size_written < output_facility->buffer_size)
1329  goto continue_partial_write;
1330 
1331  /* we are now waiting for our buffer to be filled*/
1332  output_facility->facility_state = IOSTATE_WAITING;
1333 
1334  /* we successfully wrote something and now need to reset our reader */
1335  if (IOSTATE_WAITING == input_facility->facility_state)
1336  input_facility->facility_state = IOSTATE_RESUME;
1337  else if (IOSTATE_FAILED == input_facility->facility_state)
1338  output_facility->path_open = FALSE;
1339  }
1340  else
1341  { /* operation still pending/queued or failed? */
1342  int err = GetLastError();
1343  if ((ERROR_IO_INCOMPLETE != err) && (ERROR_IO_PENDING != err))
1344  { /* error occurred, close this path */
1345  output_facility->path_open = FALSE;
1346  output_facility->facility_state = IOSTATE_FAILED;
1347  fprintf(stderr, "FATAL: Write to handle failed, exiting\n");
1348  }
1349  }
1350 
1351  default:
1352  return TRUE;
1353  }
1354 }
overlapped I/O has been queued
BOOL path_open
If the path is open or blocked in general (used for quickly checking)
there is a full buffer waiting
DWORD buffer_size_processed
Amount of data actually written or read by readfile/writefile.
DWORD buffer_size
How much of this buffer was used when reading or how much data can be written.
OVERLAPPED overlapped
Overlaped IO structure used for asynchronous IO in windows.
enum IO_State facility_state
The mode the state machine associated with this object is in.
overlapped I/O is ready for work
unsigned char buffer[65536]
Buffer for reading things to and writing from...
HANDLE handle
Windows Object-Handle (used for accessing TAP and STDIN/STDOUT)
overlapped I/O has finished, but is waiting for it&#39;s write-partner
Operlapped IO states for facility objects overlapped I/O has failed, stop processing.
DWORD buffer_size_written
How much of this buffer we have written in total.
Here is the caller graph for this function:

◆ initialize_io_facility()

static BOOL initialize_io_facility ( struct io_facility elem,
int  initial_state,
BOOL  signaled 
)
static

Initialize a overlapped structure.

Parameters
elemthe element to initilize
initial_statethe initial state for this instance
signaledif the hEvent created should default to signaled or not
Returns
true on success, else false

Definition at line 1366 of file gnunet-helper-vpn-windows.c.

References io_facility::buffer_size, io_facility::facility_state, io_facility::handle, io_facility::overlapped, and io_facility::path_open.

Referenced by run().

1369 {
1370  elem->path_open = TRUE;
1371  elem->handle = INVALID_HANDLE_VALUE;
1372  elem->facility_state = initial_state;
1373  elem->buffer_size = 0;
1374  elem->overlapped.hEvent = CreateEvent(NULL, TRUE, signaled, NULL);
1375  if (NULL == elem->overlapped.hEvent)
1376  return FALSE;
1377 
1378  return TRUE;
1379 }
BOOL path_open
If the path is open or blocked in general (used for quickly checking)
DWORD buffer_size
How much of this buffer was used when reading or how much data can be written.
OVERLAPPED overlapped
Overlaped IO structure used for asynchronous IO in windows.
enum IO_State facility_state
The mode the state machine associated with this object is in.
HANDLE handle
Windows Object-Handle (used for accessing TAP and STDIN/STDOUT)
Here is the caller graph for this function:

◆ run()

static void run ( HANDLE  tap_handle)
static

Start forwarding to and from the tunnel.

Parameters
tap_handledevice handle for interacting with the Virtual interface

Definition at line 1388 of file gnunet-helper-vpn-windows.c.

References attempt_read_stdin(), attempt_read_tap(), attempt_write(), io_facility::handle, initialize_io_facility(), IOSTATE_READY, IOSTATE_WAITING, io_facility::path_open, privilege_testing, ReOpenFile(), and tun_up().

Referenced by main().

1389 {
1390  /* IO-Facility for reading from our virtual interface */
1391  struct io_facility tap_read;
1392  /* IO-Facility for writing to our virtual interface */
1393  struct io_facility tap_write;
1394  /* IO-Facility for reading from stdin */
1395  struct io_facility std_in;
1396  /* IO-Facility for writing to stdout */
1397  struct io_facility std_out;
1398 
1399  HANDLE parent_std_in_handle = GetStdHandle(STD_INPUT_HANDLE);
1400  HANDLE parent_std_out_handle = GetStdHandle(STD_OUTPUT_HANDLE);
1401 
1402  /* tun up: */
1403  /* we do this HERE and not beforehand (in init_tun()), in contrast to openvpn
1404  * to remove the need to flush the arp cache, handle DHCP and wrong IPs.
1405  *
1406  * DHCP and such are all features we will never use in gnunet afaik.
1407  * But for openvpn those are essential.
1408  */
1409  if ((privilege_testing) || (!tun_up(tap_handle)))
1410  goto teardown_final;
1411 
1412  /* Initialize our overlapped IO structures*/
1413  if (!(initialize_io_facility(&tap_read, IOSTATE_READY, FALSE)
1414  && initialize_io_facility(&tap_write, IOSTATE_WAITING, TRUE)
1415  && initialize_io_facility(&std_in, IOSTATE_READY, FALSE)
1416  && initialize_io_facility(&std_out, IOSTATE_WAITING, TRUE)))
1417  goto teardown_final;
1418 
1419  /* Handles for STDIN and STDOUT */
1420  tap_read.handle = tap_handle;
1421  tap_write.handle = tap_handle;
1422 
1423 #ifdef DEBUG_TO_CONSOLE
1424  /* Debug output to console STDIN/STDOUT*/
1425  std_in.handle = parent_std_in_handle;
1426  std_out.handle = parent_std_out_handle;
1427 #else
1428  fprintf(stderr, "DEBUG: reopening stdin/out for overlapped IO\n");
1429  /*
1430  * Find out the types of our handles.
1431  * This part is a problem, because in windows we need to handle files,
1432  * pipes and the console differently.
1433  */
1434  if ((FILE_TYPE_PIPE != GetFileType(parent_std_in_handle)) ||
1435  (FILE_TYPE_PIPE != GetFileType(parent_std_out_handle)))
1436  {
1437  fprintf(stderr, "ERROR: stdin/stdout must be named pipes\n");
1438  goto teardown;
1439  }
1440 
1441  std_in.handle = ReOpenFile(parent_std_in_handle,
1442  GENERIC_READ,
1443  FILE_SHARE_WRITE | FILE_SHARE_READ,
1444  FILE_FLAG_OVERLAPPED);
1445 
1446  if (INVALID_HANDLE_VALUE == std_in.handle)
1447  {
1448  fprintf(stderr, "FATAL: Could not reopen stdin for in overlapped mode, has to be a named pipe\n");
1449  goto teardown;
1450  }
1451 
1452  std_out.handle = ReOpenFile(parent_std_out_handle,
1453  GENERIC_WRITE,
1454  FILE_SHARE_READ,
1455  FILE_FLAG_OVERLAPPED);
1456 
1457  if (INVALID_HANDLE_VALUE == std_out.handle)
1458  {
1459  fprintf(stderr, "FATAL: Could not reopen stdout for in overlapped mode, has to be a named pipe\n");
1460  goto teardown;
1461  }
1462 #endif
1463 
1464  fprintf(stderr, "DEBUG: mainloop has begun\n");
1465 
1466  while (std_out.path_open || tap_write.path_open)
1467  {
1468  /* perform READ from stdin if possible */
1469  if (std_in.path_open && (!attempt_read_stdin(&std_in, &tap_write)))
1470  break;
1471 
1472  /* perform READ from tap if possible */
1473  if (tap_read.path_open && (!attempt_read_tap(&tap_read, &std_out)))
1474  break;
1475 
1476  /* perform WRITE to tap if possible */
1477  if (tap_write.path_open && (!attempt_write(&tap_write, &std_in)))
1478  break;
1479 
1480  /* perform WRITE to STDOUT if possible */
1481  if (std_out.path_open && (!attempt_write(&std_out, &tap_read)))
1482  break;
1483  }
1484 
1485  fprintf(stderr, "DEBUG: teardown initiated\n");
1486 teardown:
1487  CancelIo(tap_handle);
1488  CancelIo(std_in.handle);
1489  CancelIo(std_out.handle);
1490 teardown_final:
1491  CloseHandle(tap_handle);
1492 }
static BOOL attempt_read_tap(struct io_facility *input_facility, struct io_facility *output_facility)
Attempts to read off an input facility (tap or named pipe) in overlapped mode.
static BOOL initialize_io_facility(struct io_facility *elem, int initial_state, BOOL signaled)
Initialize a overlapped structure.
static BOOL tun_up(HANDLE handle)
Brings a TAP device up and sets it to connected state.
static BOOL attempt_read_stdin(struct io_facility *input_facility, struct io_facility *output_facility)
Attempts to read off an input facility (tap or named pipe) in overlapped mode.
static boolean privilege_testing
Will this binary be run in permissions testing mode?
overlapped I/O is ready for work
WINBASEAPI HANDLE WINAPI ReOpenFile(HANDLE, DWORD, DWORD, DWORD)
ReOpenFile is only available as of XP SP2 and 2003 SP1.
overlapped I/O has finished, but is waiting for it&#39;s write-partner
static BOOL attempt_write(struct io_facility *output_facility, struct io_facility *input_facility)
Attempts to write to an output facility (tap or named pipe) in overlapped mode.
A IO Object + read/writebuffer + buffer-size for windows asynchronous IO handling.
Here is the call graph for this function:
Here is the caller graph for this function:

◆ main()

int main ( int  argc,
char **  argv 
)

Open VPN tunnel interface.

Parameters
argcmust be 6
argv0: binary name (gnunet-helper-vpn) [1: dryrun/testrun (does not execute mainloop)] 2: tunnel interface prefix (gnunet-vpn) 3: IPv6 address (::1), "-" to disable 4: IPv6 netmask length in bits (64), ignored if #2 is "-" 5: IPv4 address (1.2.3.4), "-" to disable 6: IPv4 netmask (255.255.0.0), ignored if #4 is "-"

Definition at line 1508 of file gnunet-helper-vpn-windows.c.

References address, cleanup(), global_ret, GNUNET_strlcpy(), io_facility::handle, init_tun(), privilege_testing, remove_address4(), remove_address6(), remove_interface(), run(), secondary_hwid, set_address4(), and set_address6().

1509 {
1510  char hwid[LINE_LEN];
1511  HANDLE handle;
1512  int global_ret = 0;
1513  BOOL have_ip4 = FALSE;
1514  BOOL have_ip6 = FALSE;
1515 
1516  if (argc > 1 && 0 == strcmp(argv[1], "-d"))
1517  {
1518  privilege_testing = TRUE;
1519  fprintf(stderr,
1520  "%s",
1521  "DEBUG: Running binary in privilege testing mode.");
1522  argv++;
1523  argc--;
1524  }
1525 
1526  if (6 != argc)
1527  {
1528  fprintf(stderr,
1529  "%s",
1530  "FATAL: must supply 5 arguments\nUsage:\ngnunet-helper-vpn [-d] <if name prefix> <address6 or \"-\"> <netbits6> <address4 or \"-\"> <netmask4>\n");
1531  return 1;
1532  }
1533 
1534  GNUNET_strlcpy(hwid, argv[1], sizeof(hwid));
1535 
1536  /*
1537  * We use our PID for finding/resolving the control-panel name of our virtual
1538  * device. PIDs are (of course) unique at runtime, thus we can safely use it
1539  * as additional hardware-id for our device.
1540  */
1541  snprintf(secondary_hwid, LINE_LEN / 2, "%s-%d",
1542  hwid,
1543  _getpid());
1544 
1545  if (INVALID_HANDLE_VALUE == (handle = init_tun()))
1546  {
1547  fprintf(stderr, "FATAL: could not initialize virtual-interface %s with IPv6 %s/%s and IPv4 %s/%s\n",
1548  hwid,
1549  argv[2],
1550  argv[3],
1551  argv[4],
1552  argv[5]);
1553  global_ret = -1;
1554  goto cleanup;
1555  }
1556 
1557  fprintf(stderr, "DEBUG: Setting IPs, if needed\n");
1558  if (0 != strcmp(argv[2], "-"))
1559  {
1560  const char *address = argv[2];
1561  long prefix_len = atol(argv[3]);
1562 
1563  if ((prefix_len < 1) || (prefix_len > 127))
1564  {
1565  fprintf(stderr, "FATAL: ipv6 prefix_len out of range\n");
1566  global_ret = -1;
1567  goto cleanup;
1568  }
1569 
1570  fprintf(stderr, "DEBUG: Setting IP6 address: %s/%d\n", address, prefix_len);
1571  if (0 != (global_ret = set_address6(address, prefix_len)))
1572  goto cleanup;
1573 
1574  have_ip6 = TRUE;
1575  }
1576 
1577  if (0 != strcmp(argv[4], "-"))
1578  {
1579  const char *address = argv[4];
1580  const char *mask = argv[5];
1581 
1582  fprintf(stderr, "DEBUG: Setting IP4 address: %s/%s\n", address, mask);
1583  if (0 != (global_ret = set_address4(address, mask)))
1584  goto cleanup;
1585 
1586  have_ip4 = TRUE;
1587  }
1588 
1589  run(handle);
1590 cleanup:
1591 
1592  if (have_ip4)
1593  {
1594  const char *address = argv[4];
1595  fprintf(stderr, "DEBUG: Removing IP4 address\n");
1596  remove_address4(address);
1597  }
1598  if (have_ip6)
1599  {
1600  const char *address = argv[2];
1601  fprintf(stderr, "DEBUG: Removing IP6 address\n");
1602  remove_address6(address);
1603  }
1604 
1605  fprintf(stderr, "DEBUG: removing interface\n");
1606  remove_interface();
1607  fprintf(stderr, "DEBUG: graceful exit completed\n");
1608 
1609  return global_ret;
1610 }
static BOOL remove_interface()
Remove our new virtual interface to use for tunneling.
static int set_address4(const char *address, const char *mask)
Sets the IPv4-Address given in address on the interface dev.
static void run(HANDLE tap_handle)
Start forwarding to and from the tunnel.
static void remove_address6(const char *address)
Removes the IPv6-Address given in address from the interface dev.
static char secondary_hwid[LINE_LEN/2]
Our local process&#39; PID.
static HANDLE init_tun()
Creates a tun-interface called dev;.
static void cleanup(void *cls)
Function scheduled as very last function, cleans up after us.
static struct GNUNET_DNS_Handle * handle
Handle to transport service.
static int set_address6(const char *address, unsigned long prefix_len)
Sets the IPv6-Address given in address on the interface dev.
static void remove_address4(const char *address)
Removes the IPv4-Address given in address from the interface dev.
static boolean privilege_testing
Will this binary be run in permissions testing mode?
static char * address
GNS address for this phone.
size_t GNUNET_strlcpy(char *dst, const char *src, size_t n)
Like strlcpy but portable.
static int global_ret
Return value from main.
Here is the call graph for this function:

Variable Documentation

◆ privilege_testing

boolean privilege_testing = FALSE
static

Will this binary be run in permissions testing mode?

Definition at line 77 of file gnunet-helper-vpn-windows.c.

Referenced by main(), and run().

◆ secondary_hwid

char secondary_hwid[LINE_LEN/2]
static

Our local process' PID.

Used for creating a sufficiently unique additional hardware ID for our device.

Definition at line 131 of file gnunet-helper-vpn-windows.c.

Referenced by main(), and setup_interface().

◆ device_visible_name

char device_visible_name[256]
static

Device's visible Name, used to identify a network device in netsh.

eg: "Local Area Connection 9"

Definition at line 137 of file gnunet-helper-vpn-windows.c.

Referenced by remove_address4(), remove_address6(), resolve_interface_name(), set_address4(), and set_address6().

◆ DeviceInfo

HDEVINFO DeviceInfo = INVALID_HANDLE_VALUE
static

This is our own local instance of a virtual network interface It is (somewhat) equivalent to using tun/tap in unixoid systems.

Upon initialization, we create such an device node. Upon termination, we remove it again.

If we crash this device might stay around.

Definition at line 148 of file gnunet-helper-vpn-windows.c.

Referenced by remove_interface(), and setup_interface().

◆ DeviceNode

SP_DEVINFO_DATA DeviceNode
static

Registry Key we hand over to windows to spawn a new virtual interface.

Definition at line 153 of file gnunet-helper-vpn-windows.c.

Referenced by remove_interface(), resolve_interface_name(), and setup_interface().

◆ device_guid

char device_guid[256]
static

GUID of our virtual device in the form of {12345678-1234-1234-1234-123456789abc} - in hex.

Definition at line 159 of file gnunet-helper-vpn-windows.c.

Referenced by init_tun(), and resolve_interface_name().