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 251 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.

166 {
167 
171  IOSTATE_READY = 0,
172 
177 
182 
187 
193 
194 };
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 286 of file gnunet-helper-vpn-windows.c.

Referenced by setup_interface().

287 {
288 #if defined(_WIN64)
289  //this is a win64 binary,
290  return TRUE;
291 #elif defined(_WIN32)
292  //this is a 32bit binary, and we need to check if we are running in WOW64
293  BOOL success = FALSE;
294  BOOL on_wow64 = FALSE;
295  LPFN_ISWOW64PROCESS IsWow64Process = (LPFN_ISWOW64PROCESS) GetProcAddress (GetModuleHandle ("kernel32"), "IsWow64Process");
296 
297  if (NULL != IsWow64Process)
298  success = IsWow64Process (GetCurrentProcess (), &on_wow64);
299 
300  return success && on_wow64;
301 #endif
302 }
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 312 of file gnunet-helper-vpn-windows.c.

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

313 {
314  FILE *pipe;
315 
316  if ( (NULL == command) ||
317  (NULL == (pipe = _popen (command, "rt"))) )
318  return EINVAL;
319 
320 #if DEBUG
321  fprintf (stderr, "DEBUG: Command output: \n");
322  char output[LINE_LEN];
323  while (NULL != fgets (output, sizeof (output), pipe))
324  fprintf (stderr, "%s", output);
325 #endif
326 
327  return _pclose (pipe);
328 }
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 338 of file gnunet-helper-vpn-windows.c.

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

Referenced by main().

339 {
340  int ret = EINVAL;
341  char command[LINE_LEN];
342  struct sockaddr_in6 sa6;
343 
344  /*
345  * parse the new address
346  */
347  memset (&sa6, 0, sizeof (struct sockaddr_in6));
348  sa6.sin6_family = AF_INET6;
349  if (1 != inet_pton (AF_INET6, address, &sa6.sin6_addr.s6_addr))
350  {
351  fprintf (stderr, "ERROR: Failed to parse address `%s': %s\n", address,
352  strerror (errno));
353  return -1;
354  }
355 
356  /*
357  * prepare the command
358  */
359  snprintf (command, LINE_LEN,
360  "netsh interface ipv6 add address \"%s\" %s/%d store=active",
361  device_visible_name, address, prefix_len);
362  /*
363  * Set the address
364  */
365  ret = execute_shellcommand (command);
366 
367  /* Did it work?*/
368  if (0 != ret)
369  fprintf (stderr, "FATAL: Setting IPv6 address failed: %s\n", strerror (ret));
370  return ret;
371 }
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 380 of file gnunet-helper-vpn-windows.c.

References device_visible_name, execute_shellcommand(), and ret.

Referenced by main().

381 {
382  char command[LINE_LEN];
383  int ret = EINVAL;
384 
385  // sanity checking was already done in set_address6
386  /*
387  * prepare the command
388  */
389  snprintf (command, LINE_LEN,
390  "netsh interface ipv6 delete address \"%s\" store=persistent",
392  /*
393  * Set the address
394  */
395  ret = execute_shellcommand (command);
396 
397  /* Did it work?*/
398  if (0 != ret)
399  fprintf (stderr,
400  "FATAL: removing IPv6 address failed: %s\n",
401  strerror (ret));
402 }
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 412 of file gnunet-helper-vpn-windows.c.

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

Referenced by main().

413 {
414  int ret = EINVAL;
415  char command[LINE_LEN];
416 
417  struct sockaddr_in addr;
418  addr.sin_family = AF_INET;
419 
420  /*
421  * Parse the address
422  */
423  if (1 != inet_pton (AF_INET, address, &addr.sin_addr.s_addr))
424  {
425  fprintf (stderr, "ERROR: Failed to parse address `%s': %s\n", address,
426  strerror (errno));
427  return -1;
428  }
429  // Set Device to Subnet-Mode? do we really need openvpn/tun.c:2925 ?
430 
431  /*
432  * prepare the command
433  */
434  snprintf (command, LINE_LEN,
435  "netsh interface ipv4 add address \"%s\" %s %s store=active",
437  /*
438  * Set the address
439  */
440  ret = execute_shellcommand (command);
441 
442  /* Did it work?*/
443  if (0 != ret)
444  fprintf (stderr,
445  "FATAL: Setting IPv4 address failed: %s\n",
446  strerror (ret));
447  return ret;
448 }
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 457 of file gnunet-helper-vpn-windows.c.

References device_visible_name, execute_shellcommand(), and ret.

Referenced by main().

458 {
459  char command[LINE_LEN];
460  int ret = EINVAL;
461 
462  // sanity checking was already done in set_address4
463 
464  /*
465  * prepare the command
466  */
467  snprintf (command, LINE_LEN,
468  "netsh interface ipv4 delete address \"%s\" gateway=all store=persistent",
470  /*
471  * Set the address
472  */
473  ret = execute_shellcommand (command);
474 
475  /* Did it work?*/
476  if (0 != ret)
477  fprintf (stderr, "FATAL: removing IPv4 address failed: %s\n", strerror (ret));
478 }
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 487 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().

488 {
489  /*
490  * where to find our inf-file. (+ the "full" path, after windows found")
491  *
492  * We do not directly input all the props here, because openvpn will update
493  * these details over time.
494  */
495  char inf_file_path[MAX_PATH];
496  char * temp_inf_filename;
497  char hwidlist[LINE_LEN + 4];
498  char class_name[128];
499  GUID class_guid;
500  int str_length = 0;
501 
506  str_len = GNUNET_strlcpy (hwidlist,
507  HARDWARE_ID,
508  sizeof (hwidList)) + 1;
515  str_len += GNUNET_strlcpy (&hwidlist[str_length],
517  sizeof (hwidlist) - str_len) + 1;
518  GNUNET_assert (str_len < sizeof (hwidlist));
519  hwidlist[str_len] = '\0';
520  ++str_len;
521 
526  if (is_win64())
527  GetFullPathNameA (INF_FILE64, MAX_PATH, inf_file_path, &temp_inf_filename);
528  else
529  GetFullPathNameA (INF_FILE, MAX_PATH, inf_file_path, &temp_inf_filename);
530 
531  fprintf (stderr, "INFO: Located our driver's .inf file at %s\n", inf_file_path);
535  if ( ! SetupDiGetINFClassA (inf_file_path,
536  &class_guid,
537  class_name, sizeof (class_name) / sizeof (char),
538  NULL))
539  return FALSE;
540 
545  DeviceInfo = SetupDiCreateDeviceInfoList (&class_guid, NULL);
546  if (DeviceInfo == INVALID_HANDLE_VALUE)
547  return FALSE;
548 
549  DeviceNode.cbSize = sizeof (SP_DEVINFO_DATA);
550  if ( ! SetupDiCreateDeviceInfoA (DeviceInfo,
551  class_name,
552  &class_guid,
553  NULL,
554  0,
555  DICD_GENERATE_ID,
556  &DeviceNode))
557  return FALSE;
558 
559  /* Deploy all the information collected into the registry */
560  if ( ! SetupDiSetDeviceRegistryPropertyA (DeviceInfo,
561  &DeviceNode,
562  SPDRP_HARDWAREID,
563  (LPBYTE) hwidlist,
564  str_length * sizeof (char)))
565  return FALSE;
566 
567  /* Install our new class(=device) into the system */
568  if ( ! SetupDiCallClassInstaller (DIF_REGISTERDEVICE,
569  DeviceInfo,
570  &DeviceNode))
571  return FALSE;
572 
573  /* This system call tends to take a while (several seconds!) on
574  "modern" Windoze systems */
575  if ( ! UpdateDriverForPlugAndPlayDevicesA (NULL,
577  inf_file_path,
578  INSTALLFLAG_FORCE | INSTALLFLAG_NONINTERACTIVE,
579  NULL)) //reboot required? NEVER!
580  return FALSE;
581 
582  fprintf (stderr, "DEBUG: successfully created a network device\n");
583  return TRUE;
584 }
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 594 of file gnunet-helper-vpn-windows.c.

References DeviceInfo, and DeviceNode.

Referenced by main().

595 {
596  SP_REMOVEDEVICE_PARAMS remove;
597 
598  if (INVALID_HANDLE_VALUE == DeviceInfo)
599  return FALSE;
600 
601  remove.ClassInstallHeader.cbSize = sizeof (SP_CLASSINSTALL_HEADER);
602  remove.HwProfile = 0;
603  remove.Scope = DI_REMOVEDEVICE_GLOBAL;
604  remove.ClassInstallHeader.InstallFunction = DIF_REMOVE;
605  /*
606  * 1. Prepare our existing device information set, and place the
607  * uninstall related information into the structure
608  */
609  if ( ! SetupDiSetClassInstallParamsA (DeviceInfo,
610  (PSP_DEVINFO_DATA) & DeviceNode,
611  &remove.ClassInstallHeader,
612  sizeof (remove)))
613  return FALSE;
614  /*
615  * 2. Uninstall the virtual interface using the class installer
616  */
617  if ( ! SetupDiCallClassInstaller (DIF_REMOVE,
618  DeviceInfo,
619  (PSP_DEVINFO_DATA) & DeviceNode))
620  return FALSE;
621 
622  SetupDiDestroyDeviceInfoList (DeviceInfo);
623 
624  fprintf (stderr, "DEBUG: removed interface successfully\n");
625 
626  return TRUE;
627 }
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 637 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().

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

779 {
780  ULONG version[3];
781  DWORD len;
782  memset (&(version), 0, sizeof (version));
783 
784  if (DeviceIoControl (handle, TAP_WIN_IOCTL_GET_VERSION,
785  &version, sizeof (version),
786  &version, sizeof (version), &len, NULL))
787  fprintf (stderr, "INFO: TAP-Windows Driver Version %d.%d %s\n",
788  (int) version[0],
789  (int) version[1],
790  (version[2] ? "(DEBUG)" : ""));
791 
792  if ((version[0] != TAP_WIN_MIN_MAJOR) ||
793  (version[1] < TAP_WIN_MIN_MINOR )){
794  fprintf (stderr, "FATAL: This version of gnunet requires a TAP-Windows driver that is at least version %d.%d\n",
797  return FALSE;
798  }
799 
800  return TRUE;
801 }
#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 810 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().

811 {
812  char device_path[256];
813  HANDLE handle;
814 
815  if (! setup_interface ())
816  {
817  errno = ENODEV;
818  return INVALID_HANDLE_VALUE;
819  }
820 
821  if (! resolve_interface_name ())
822  {
823  errno = ENODEV;
824  return INVALID_HANDLE_VALUE;
825  }
826 
827  /* Open Windows TAP-Windows adapter */
828  snprintf (device_path, sizeof (device_path), "%s%s%s",
830  device_guid,
832 
833  handle = CreateFile (
834  device_path,
835  GENERIC_READ | GENERIC_WRITE,
836  0, /* was: FILE_SHARE_READ */
837  0,
838  OPEN_EXISTING,
839  FILE_ATTRIBUTE_SYSTEM | FILE_FLAG_OVERLAPPED,
840  0
841  );
842 
843  if (INVALID_HANDLE_VALUE == handle)
844  {
845  fprintf (stderr, "FATAL: CreateFile failed on TAP device: %s\n", device_path);
846  return handle;
847  }
848 
849  /* get driver version info */
850  if (! check_tapw32_version (handle))
851  {
852  CloseHandle (handle);
853  return INVALID_HANDLE_VALUE;
854  }
855 
856  /* TODO (opt?): get MTU-Size */
857 
858  fprintf (stderr, "DEBUG: successfully opened TAP device\n");
859  return handle;
860 }
#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 870 of file gnunet-helper-vpn-windows.c.

References len, status, TAP32_POSTUP_WAITTIME, and TAP_WIN_IOCTL_SET_MEDIA_STATUS.

Referenced by run().

871 {
872  ULONG status = TRUE;
873  DWORD len;
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 
941  /* reset event manually*/
942  if (! SetEvent (input_facility->overlapped.hEvent))
943  return FALSE;
944 
945  fprintf (stderr, "DEBUG: tap read succeeded immediately\n");
946 
947  /* we successfully read something from the TAP and now need to
948  * send it our via STDOUT. Is that possible at the moment? */
949  if ((IOSTATE_READY == output_facility->facility_state ||
950  IOSTATE_WAITING == output_facility->facility_state)
951  && (0 < input_facility->buffer_size))
952  { /* hand over this buffers content and apply message header for gnunet */
953  hdr = (struct GNUNET_MessageHeader *) output_facility->buffer;
954  size = input_facility->buffer_size + sizeof (struct GNUNET_MessageHeader);
955 
956  GNUNET_memcpy (output_facility->buffer + sizeof (struct GNUNET_MessageHeader),
957  input_facility->buffer,
958  input_facility->buffer_size);
959 
960  output_facility->buffer_size = size;
961  hdr->size = htons (size);
962  hdr->type = htons (GNUNET_MESSAGE_TYPE_VPN_HELPER);
963  output_facility->facility_state = IOSTATE_READY;
964  }
965  else if (0 < input_facility->buffer_size)
966  /* If we have have read our buffer, wait for our write-partner*/
967  input_facility->facility_state = IOSTATE_WAITING;
968  }
969  else /* operation was either queued or failed*/
970  {
971  int err = GetLastError ();
972  if (ERROR_IO_PENDING == err)
973  { /* operation queued */
974  input_facility->facility_state = IOSTATE_QUEUED;
975  }
976  else
977  { /* error occurred, let the rest of the elements finish */
978  input_facility->path_open = FALSE;
979  input_facility->facility_state = IOSTATE_FAILED;
980  if (IOSTATE_WAITING == output_facility->facility_state)
981  output_facility->path_open = FALSE;
982 
983  fprintf (stderr, "FATAL: Read from handle failed, allowing write to finish\n");
984  }
985  }
986  }
987  return TRUE;
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  case IOSTATE_RESUME:
1043  hdr = (struct GNUNET_MessageHeader *) output_facility->buffer;
1044  size = input_facility->buffer_size + sizeof (struct GNUNET_MessageHeader);
1045 
1046  GNUNET_memcpy (output_facility->buffer + sizeof (struct GNUNET_MessageHeader),
1047  input_facility->buffer,
1048  input_facility->buffer_size);
1049 
1050  output_facility->buffer_size = size;
1051  hdr->size = htons (size);
1052  hdr->type = htons (GNUNET_MESSAGE_TYPE_VPN_HELPER);
1053  output_facility->facility_state = IOSTATE_READY;
1054  input_facility->facility_state = IOSTATE_READY;
1055  return TRUE;
1056  default:
1057  return TRUE;
1058  }
1059 }
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:67
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 1089 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().

1091 {
1092  struct GNUNET_MessageHeader * hdr;
1093 
1094  switch (input_facility->facility_state)
1095  {
1096  case IOSTATE_READY:
1097  {
1098  input_facility->buffer_size = 0;
1099 
1100 partial_read_iostate_ready:
1101  if (! ResetEvent (input_facility->overlapped.hEvent))
1102  return FALSE;
1103 
1104  /* Check how the task is handled */
1105  if (ReadFile (input_facility->handle,
1106  input_facility->buffer + input_facility->buffer_size,
1107  sizeof (input_facility->buffer) - input_facility->buffer_size,
1108  &input_facility->buffer_size_processed,
1109  &input_facility->overlapped))
1110  {/* async event processed immediately*/
1111  hdr = (struct GNUNET_MessageHeader *) input_facility->buffer;
1112 
1113  /* reset event manually*/
1114  if (!SetEvent (input_facility->overlapped.hEvent))
1115  return FALSE;
1116 
1117  fprintf (stderr, "DEBUG: stdin read succeeded immediately\n");
1118  input_facility->buffer_size += input_facility->buffer_size_processed;
1119 
1120  if (ntohs (hdr->type) != GNUNET_MESSAGE_TYPE_VPN_HELPER ||
1121  ntohs (hdr->size) > sizeof (input_facility->buffer))
1122  {
1123  fprintf (stderr, "WARNING: Protocol violation, got GNUnet Message type %h, size %h\n", ntohs (hdr->type), ntohs (hdr->size));
1124  input_facility->facility_state = IOSTATE_READY;
1125  return TRUE;
1126  }
1127  /* we got the a part of a packet */
1128  if (ntohs (hdr->size) > input_facility->buffer_size)
1129  goto partial_read_iostate_ready;
1130 
1131  /* have we read more than 0 bytes of payload? (sizeread > header)*/
1132  if (input_facility->buffer_size > sizeof (struct GNUNET_MessageHeader) &&
1133  ((IOSTATE_READY == output_facility->facility_state) ||
1134  (IOSTATE_WAITING == output_facility->facility_state)))
1135  {/* we successfully read something from the TAP and now need to
1136  * send it our via STDOUT. Is that possible at the moment? */
1137 
1138  /* hand over this buffers content and strip gnunet message header */
1139  GNUNET_memcpy (output_facility->buffer,
1140  input_facility->buffer + sizeof (struct GNUNET_MessageHeader),
1141  input_facility->buffer_size - sizeof (struct GNUNET_MessageHeader));
1142  output_facility->buffer_size = input_facility->buffer_size - sizeof (struct GNUNET_MessageHeader);
1143  output_facility->facility_state = IOSTATE_READY;
1144  input_facility->facility_state = IOSTATE_READY;
1145  }
1146  else if (input_facility->buffer_size > sizeof (struct GNUNET_MessageHeader))
1147  /* If we have have read our buffer, wait for our write-partner*/
1148  input_facility->facility_state = IOSTATE_WAITING;
1149  else /* we read nothing */
1150  input_facility->facility_state = IOSTATE_READY;
1151  }
1152  else /* operation was either queued or failed*/
1153  {
1154  int err = GetLastError ();
1155  if (ERROR_IO_PENDING == err) /* operation queued */
1156  input_facility->facility_state = IOSTATE_QUEUED;
1157  else
1158  { /* error occurred, let the rest of the elements finish */
1159  input_facility->path_open = FALSE;
1160  input_facility->facility_state = IOSTATE_FAILED;
1161  if (IOSTATE_WAITING == output_facility->facility_state)
1162  output_facility->path_open = FALSE;
1163 
1164  fprintf (stderr, "FATAL: Read from handle failed, allowing write to finish\n");
1165  }
1166  }
1167  }
1168  return TRUE;
1169  // We are queued and should check if the read has finished
1170  case IOSTATE_QUEUED:
1171  {
1172  // there was an operation going on already, check if that has completed now.
1173  if (GetOverlappedResult (input_facility->handle,
1174  &input_facility->overlapped,
1175  &input_facility->buffer_size_processed,
1176  FALSE))
1177  {/* successful return for a queued operation */
1178  hdr = (struct GNUNET_MessageHeader *) input_facility->buffer;
1179 
1180  if (! ResetEvent (input_facility->overlapped.hEvent))
1181  return FALSE;
1182 
1183  fprintf (stderr, "DEBUG: stdin read succeeded delayed\n");
1184  input_facility->buffer_size += input_facility->buffer_size_processed;
1185 
1186  if ((ntohs (hdr->type) != GNUNET_MESSAGE_TYPE_VPN_HELPER) ||
1187  (ntohs (hdr->size) > sizeof (input_facility->buffer)))
1188  {
1189  fprintf (stderr, "WARNING: Protocol violation, got GNUnet Message type %h, size %h\n", ntohs (hdr->type), ntohs (hdr->size));
1190  input_facility->facility_state = IOSTATE_READY;
1191  return TRUE;
1192  }
1193  /* we got the a part of a packet */
1194  if (ntohs (hdr->size) > input_facility->buffer_size );
1195  goto partial_read_iostate_ready;
1196 
1197  /* we successfully read something from the TAP and now need to
1198  * send it our via STDOUT. Is that possible at the moment? */
1199  if ((IOSTATE_READY == output_facility->facility_state ||
1200  IOSTATE_WAITING == output_facility->facility_state)
1201  && input_facility->buffer_size > sizeof(struct GNUNET_MessageHeader))
1202  { /* hand over this buffers content and strip gnunet message header */
1203  GNUNET_memcpy (output_facility->buffer,
1204  input_facility->buffer + sizeof(struct GNUNET_MessageHeader),
1205  input_facility->buffer_size - sizeof(struct GNUNET_MessageHeader));
1206  output_facility->buffer_size = input_facility->buffer_size - sizeof(struct GNUNET_MessageHeader);
1207  output_facility->facility_state = IOSTATE_READY;
1208  input_facility->facility_state = IOSTATE_READY;
1209  }
1210  else if (input_facility->buffer_size > sizeof(struct GNUNET_MessageHeader))
1211  input_facility->facility_state = IOSTATE_WAITING;
1212  else
1213  input_facility->facility_state = IOSTATE_READY;
1214  }
1215  else
1216  { /* operation still pending/queued or failed? */
1217  int err = GetLastError ();
1218  if ((ERROR_IO_INCOMPLETE != err) && (ERROR_IO_PENDING != err))
1219  { /* error occurred, let the rest of the elements finish */
1220  input_facility->path_open = FALSE;
1221  input_facility->facility_state = IOSTATE_FAILED;
1222  if (IOSTATE_WAITING == output_facility->facility_state)
1223  output_facility->path_open = FALSE;
1224  fprintf (stderr, "FATAL: Read from handle failed, allowing write to finish\n");
1225  }
1226  }
1227  }
1228  return TRUE;
1229  case IOSTATE_RESUME: /* Our buffer was filled already but our write facility was busy. */
1230  GNUNET_memcpy (output_facility->buffer,
1231  input_facility->buffer + sizeof (struct GNUNET_MessageHeader),
1232  input_facility->buffer_size - sizeof (struct GNUNET_MessageHeader));
1233  output_facility->buffer_size = input_facility->buffer_size - sizeof (struct GNUNET_MessageHeader);
1234  output_facility->facility_state = IOSTATE_READY;
1235  input_facility->facility_state = IOSTATE_READY;
1236  return TRUE;
1237  default:
1238  return TRUE;
1239  }
1240 }
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 1253 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().

1255 {
1256  switch (output_facility->facility_state)
1257  {
1258  case IOSTATE_READY:
1259  output_facility->buffer_size_written = 0;
1260 
1261 continue_partial_write:
1262  if (! ResetEvent (output_facility->overlapped.hEvent))
1263  return FALSE;
1264 
1265  /* Check how the task was handled */
1266  if (WriteFile (output_facility->handle,
1267  output_facility->buffer + output_facility->buffer_size_written,
1268  output_facility->buffer_size - output_facility->buffer_size_written,
1269  &output_facility->buffer_size_processed,
1270  &output_facility->overlapped))
1271  {/* async event processed immediately*/
1272 
1273  fprintf (stderr, "DEBUG: write succeeded immediately\n");
1274  output_facility->buffer_size_written += output_facility->buffer_size_processed;
1275 
1276  /* reset event manually*/
1277  if (! SetEvent (output_facility->overlapped.hEvent))
1278  return FALSE;
1279 
1280  /* partial write */
1281  if (output_facility->buffer_size_written < output_facility->buffer_size)
1282  goto continue_partial_write;
1283 
1284  /* we are now waiting for our buffer to be filled*/
1285  output_facility->facility_state = IOSTATE_WAITING;
1286 
1287  /* we successfully wrote something and now need to reset our reader */
1288  if (IOSTATE_WAITING == input_facility->facility_state)
1289  input_facility->facility_state = IOSTATE_RESUME;
1290  else if (IOSTATE_FAILED == input_facility->facility_state)
1291  output_facility->path_open = FALSE;
1292  }
1293  else /* operation was either queued or failed*/
1294  {
1295  int err = GetLastError ();
1296  if (ERROR_IO_PENDING == err)
1297  { /* operation queued */
1298  output_facility->facility_state = IOSTATE_QUEUED;
1299  }
1300  else
1301  { /* error occurred, close this path */
1302  output_facility->path_open = FALSE;
1303  output_facility->facility_state = IOSTATE_FAILED;
1304  fprintf (stderr, "FATAL: Write to handle failed, exiting\n");
1305  }
1306  }
1307  return TRUE;
1308  case IOSTATE_QUEUED:
1309  // there was an operation going on already, check if that has completed now.
1310 
1311  if (GetOverlappedResult (output_facility->handle,
1312  &output_facility->overlapped,
1313  &output_facility->buffer_size_processed,
1314  FALSE))
1315  {/* successful return for a queued operation */
1316  if (! ResetEvent (output_facility->overlapped.hEvent))
1317  return FALSE;
1318 
1319  fprintf (stderr, "DEBUG: write succeeded delayed\n");
1320  output_facility->buffer_size_written += output_facility->buffer_size_processed;
1321 
1322  /* partial write */
1323  if (output_facility->buffer_size_written < output_facility->buffer_size)
1324  goto continue_partial_write;
1325 
1326  /* we are now waiting for our buffer to be filled*/
1327  output_facility->facility_state = IOSTATE_WAITING;
1328 
1329  /* we successfully wrote something and now need to reset our reader */
1330  if (IOSTATE_WAITING == input_facility->facility_state)
1331  input_facility->facility_state = IOSTATE_RESUME;
1332  else if (IOSTATE_FAILED == input_facility->facility_state)
1333  output_facility->path_open = FALSE;
1334  }
1335  else
1336  { /* operation still pending/queued or failed? */
1337  int err = GetLastError ();
1338  if ((ERROR_IO_INCOMPLETE != err) && (ERROR_IO_PENDING != err))
1339  { /* error occurred, close this path */
1340  output_facility->path_open = FALSE;
1341  output_facility->facility_state = IOSTATE_FAILED;
1342  fprintf (stderr, "FATAL: Write to handle failed, exiting\n");
1343  }
1344  }
1345  default:
1346  return TRUE;
1347  }
1348 }
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 1360 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().

1363 {
1364  elem->path_open = TRUE;
1365  elem->handle = INVALID_HANDLE_VALUE;
1366  elem->facility_state = initial_state;
1367  elem->buffer_size = 0;
1368  elem->overlapped.hEvent = CreateEvent (NULL, TRUE, signaled, NULL);
1369  if (NULL == elem->overlapped.hEvent)
1370  return FALSE;
1371 
1372  return TRUE;
1373 }
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 1382 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().

1383 {
1384  /* IO-Facility for reading from our virtual interface */
1385  struct io_facility tap_read;
1386  /* IO-Facility for writing to our virtual interface */
1387  struct io_facility tap_write;
1388  /* IO-Facility for reading from stdin */
1389  struct io_facility std_in;
1390  /* IO-Facility for writing to stdout */
1391  struct io_facility std_out;
1392 
1393  HANDLE parent_std_in_handle = GetStdHandle (STD_INPUT_HANDLE);
1394  HANDLE parent_std_out_handle = GetStdHandle (STD_OUTPUT_HANDLE);
1395 
1396  /* tun up: */
1397  /* we do this HERE and not beforehand (in init_tun()), in contrast to openvpn
1398  * to remove the need to flush the arp cache, handle DHCP and wrong IPs.
1399  *
1400  * DHCP and such are all features we will never use in gnunet afaik.
1401  * But for openvpn those are essential.
1402  */
1403  if ((privilege_testing) || (! tun_up (tap_handle)))
1404  goto teardown_final;
1405 
1406  /* Initialize our overlapped IO structures*/
1407  if (! (initialize_io_facility (&tap_read, IOSTATE_READY, FALSE)
1408  && initialize_io_facility (&tap_write, IOSTATE_WAITING, TRUE)
1409  && initialize_io_facility (&std_in, IOSTATE_READY, FALSE)
1410  && initialize_io_facility (&std_out, IOSTATE_WAITING, TRUE)))
1411  goto teardown_final;
1412 
1413  /* Handles for STDIN and STDOUT */
1414  tap_read.handle = tap_handle;
1415  tap_write.handle = tap_handle;
1416 
1417 #ifdef DEBUG_TO_CONSOLE
1418  /* Debug output to console STDIN/STDOUT*/
1419  std_in.handle = parent_std_in_handle;
1420  std_out.handle = parent_std_out_handle;
1421 
1422 #else
1423  fprintf (stderr, "DEBUG: reopening stdin/out for overlapped IO\n");
1424  /*
1425  * Find out the types of our handles.
1426  * This part is a problem, because in windows we need to handle files,
1427  * pipes and the console differently.
1428  */
1429  if ((FILE_TYPE_PIPE != GetFileType (parent_std_in_handle)) ||
1430  (FILE_TYPE_PIPE != GetFileType (parent_std_out_handle)))
1431  {
1432  fprintf (stderr, "ERROR: stdin/stdout must be named pipes\n");
1433  goto teardown;
1434  }
1435 
1436  std_in.handle = ReOpenFile (parent_std_in_handle,
1437  GENERIC_READ,
1438  FILE_SHARE_WRITE | FILE_SHARE_READ,
1439  FILE_FLAG_OVERLAPPED);
1440 
1441  if (INVALID_HANDLE_VALUE == std_in.handle)
1442  {
1443  fprintf (stderr, "FATAL: Could not reopen stdin for in overlapped mode, has to be a named pipe\n");
1444  goto teardown;
1445  }
1446 
1447  std_out.handle = ReOpenFile (parent_std_out_handle,
1448  GENERIC_WRITE,
1449  FILE_SHARE_READ,
1450  FILE_FLAG_OVERLAPPED);
1451 
1452  if (INVALID_HANDLE_VALUE == std_out.handle)
1453  {
1454  fprintf (stderr, "FATAL: Could not reopen stdout for in overlapped mode, has to be a named pipe\n");
1455  goto teardown;
1456  }
1457 #endif
1458 
1459  fprintf (stderr, "DEBUG: mainloop has begun\n");
1460 
1461  while (std_out.path_open || tap_write.path_open)
1462  {
1463  /* perform READ from stdin if possible */
1464  if (std_in.path_open && (! attempt_read_stdin (&std_in, &tap_write)))
1465  break;
1466 
1467  /* perform READ from tap if possible */
1468  if (tap_read.path_open && (! attempt_read_tap (&tap_read, &std_out)))
1469  break;
1470 
1471  /* perform WRITE to tap if possible */
1472  if (tap_write.path_open && (! attempt_write (&tap_write, &std_in)))
1473  break;
1474 
1475  /* perform WRITE to STDOUT if possible */
1476  if (std_out.path_open && (! attempt_write (&std_out, &tap_read)))
1477  break;
1478  }
1479 
1480  fprintf (stderr, "DEBUG: teardown initiated\n");
1481 teardown:
1482  CancelIo (tap_handle);
1483  CancelIo (std_in.handle);
1484  CancelIo (std_out.handle);
1485 teardown_final:
1486  CloseHandle (tap_handle);
1487 }
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 1503 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().

1504 {
1505  char hwid[LINE_LEN];
1506  HANDLE handle;
1507  int global_ret = 0;
1508  BOOL have_ip4 = FALSE;
1509  BOOL have_ip6 = FALSE;
1510 
1511  if (argc > 1 && 0 == strcmp (argv[1], "-d")){
1512  privilege_testing = TRUE;
1513  fprintf (stderr,
1514  "%s",
1515  "DEBUG: Running binary in privilege testing mode.");
1516  argv++;
1517  argc--;
1518  }
1519 
1520  if (6 != argc)
1521  {
1522  fprintf (stderr,
1523  "%s",
1524  "FATAL: must supply 5 arguments\nUsage:\ngnunet-helper-vpn [-d] <if name prefix> <address6 or \"-\"> <netbits6> <address4 or \"-\"> <netmask4>\n");
1525  return 1;
1526  }
1527 
1528  GNUNET_strlcpy (hwid, argv[1], sizeof (hwid));
1529 
1530  /*
1531  * We use our PID for finding/resolving the control-panel name of our virtual
1532  * device. PIDs are (of course) unique at runtime, thus we can safely use it
1533  * as additional hardware-id for our device.
1534  */
1535  snprintf (secondary_hwid, LINE_LEN / 2, "%s-%d",
1536  hwid,
1537  _getpid ());
1538 
1539  if (INVALID_HANDLE_VALUE == (handle = init_tun ()))
1540  {
1541  fprintf (stderr, "FATAL: could not initialize virtual-interface %s with IPv6 %s/%s and IPv4 %s/%s\n",
1542  hwid,
1543  argv[2],
1544  argv[3],
1545  argv[4],
1546  argv[5]);
1547  global_ret = -1;
1548  goto cleanup;
1549  }
1550 
1551  fprintf (stderr, "DEBUG: Setting IPs, if needed\n");
1552  if (0 != strcmp (argv[2], "-"))
1553  {
1554  const char *address = argv[2];
1555  long prefix_len = atol (argv[3]);
1556 
1557  if ((prefix_len < 1) || (prefix_len > 127))
1558  {
1559  fprintf (stderr, "FATAL: ipv6 prefix_len out of range\n");
1560  global_ret = -1;
1561  goto cleanup;
1562  }
1563 
1564  fprintf (stderr, "DEBUG: Setting IP6 address: %s/%d\n",address,prefix_len);
1565  if (0 != (global_ret = set_address6 (address, prefix_len)))
1566  goto cleanup;
1567 
1568  have_ip6 = TRUE;
1569  }
1570 
1571  if (0 != strcmp (argv[4], "-"))
1572  {
1573  const char *address = argv[4];
1574  const char *mask = argv[5];
1575 
1576  fprintf (stderr, "DEBUG: Setting IP4 address: %s/%s\n",address,mask);
1577  if (0 != (global_ret = set_address4 (address, mask)))
1578  goto cleanup;
1579 
1580  have_ip4 = TRUE;
1581  }
1582 
1583  run (handle);
1584 cleanup:
1585 
1586  if (have_ip4)
1587  {
1588  const char *address = argv[4];
1589  fprintf (stderr, "DEBUG: Removing IP4 address\n");
1590  remove_address4 (address);
1591  }
1592  if (have_ip6)
1593  {
1594  const char *address = argv[2];
1595  fprintf (stderr, "DEBUG: Removing IP6 address\n");
1596  remove_address6 (address);
1597  }
1598 
1599  fprintf (stderr, "DEBUG: removing interface\n");
1600  remove_interface ();
1601  fprintf (stderr, "DEBUG: graceful exit completed\n");
1602 
1603  return global_ret;
1604 }
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().