diff options
author | Christian Fuchs <christian.fuchs@cfuchs.net> | 2012-12-12 21:22:57 +0000 |
---|---|---|
committer | Christian Fuchs <christian.fuchs@cfuchs.net> | 2012-12-12 21:22:57 +0000 |
commit | 530b55e3cf376821a4e28cfdd86f82e151c6f28f (patch) | |
tree | b37cb0c9d9be9cf7b966acee32f966ba3bdb11b6 /src/vpn/gnunet-helper-vpn-windows.c | |
parent | 6401897402591c23caa12ecf9258dc179368cdc3 (diff) | |
download | gnunet-530b55e3cf376821a4e28cfdd86f82e151c6f28f.tar.gz gnunet-530b55e3cf376821a4e28cfdd86f82e151c6f28f.zip |
Added basic functionality for setting IPv4/V6 addresses in win32 using
netsh.
Added wrapper for launching programs in a windows shell.
Added define for _tpopen
Diffstat (limited to 'src/vpn/gnunet-helper-vpn-windows.c')
-rw-r--r-- | src/vpn/gnunet-helper-vpn-windows.c | 242 |
1 files changed, 131 insertions, 111 deletions
diff --git a/src/vpn/gnunet-helper-vpn-windows.c b/src/vpn/gnunet-helper-vpn-windows.c index 03da4ed60..a4c020186 100644 --- a/src/vpn/gnunet-helper-vpn-windows.c +++ b/src/vpn/gnunet-helper-vpn-windows.c | |||
@@ -77,6 +77,15 @@ | |||
77 | */ | 77 | */ |
78 | #define INTERFACE_REGISTRY_LOCATION "SYSTEM\\CurrentControlSet\\Control\\Network\\{4D36E972-E325-11CE-BFC1-08002BE10318}" | 78 | #define INTERFACE_REGISTRY_LOCATION "SYSTEM\\CurrentControlSet\\Control\\Network\\{4D36E972-E325-11CE-BFC1-08002BE10318}" |
79 | 79 | ||
80 | /** | ||
81 | * TCHAR wrappers, which is missing in mingw's includes: | ||
82 | */ | ||
83 | #ifdef _UNICODE | ||
84 | #define _tpopen _wpopen | ||
85 | #else | ||
86 | #define _tpopen _popen | ||
87 | #endif | ||
88 | |||
80 | /* | 89 | /* |
81 | * Our local process' PID. Used for creating a sufficiently unique additional | 90 | * Our local process' PID. Used for creating a sufficiently unique additional |
82 | * hardware ID for our device. | 91 | * hardware ID for our device. |
@@ -117,41 +126,68 @@ static TCHAR class[128]; | |||
117 | static GUID guid; | 126 | static GUID guid; |
118 | 127 | ||
119 | /** | 128 | /** |
129 | * Wrapper for executing a shellcommand in windows. | ||
130 | * | ||
131 | * @param command - the command + parameters to execute | ||
132 | * @return * exitcode of the program executed, | ||
133 | * * EINVAL (cmd/file not found) | ||
134 | * * EPIPE (could not read STDOUT) | ||
135 | */ | ||
136 | static int | ||
137 | execute_shellcommand (TCHAR * command) | ||
138 | { | ||
139 | FILE *pipe; | ||
140 | |||
141 | if (NULL == command || | ||
142 | NULL == (pipe = _tpopen (command, "rt"))) | ||
143 | return EINVAL; | ||
144 | |||
145 | #ifdef TESTING | ||
146 | { | ||
147 | TCHAR output[LINE_LEN]; | ||
148 | |||
149 | _tprintf (_T ("executed command: %s"), command); | ||
150 | while (NULL != _fgetts (output, sizeof (output), pipe)) | ||
151 | _tprintf (output); | ||
152 | } | ||
153 | #endif | ||
154 | |||
155 | if (!feof (pipe)) | ||
156 | return EPIPE; | ||
157 | |||
158 | return _pclose (pipe); | ||
159 | } | ||
160 | |||
161 | /** | ||
120 | * @brief Sets the IPv6-Address given in address on the interface dev | 162 | * @brief Sets the IPv6-Address given in address on the interface dev |
121 | * | 163 | * |
122 | * @param address the IPv6-Address | 164 | * @param address the IPv6-Address |
123 | * @param prefix_len the length of the network-prefix | 165 | * @param prefix_len the length of the network-prefix |
124 | */ | 166 | */ |
125 | static void | 167 | static void |
126 | set_address6 (const char *address, unsigned long prefix_len) | 168 | set_address6 (const TCHAR *address, unsigned long prefix_len) |
127 | { | 169 | { |
128 | int fd = -1; | 170 | int ret = EINVAL; |
171 | TCHAR command[LINE_LEN]; | ||
129 | 172 | ||
130 | /* | 173 | /* TODO: Check if address makes sense? */ |
131 | * parse the new address | ||
132 | */ | ||
133 | 174 | ||
134 | /* | 175 | /* |
135 | * Get the index of the if | 176 | * prepare the command |
136 | */ | 177 | */ |
137 | 178 | ||
179 | _sntprintf (command, LINE_LEN, | ||
180 | _T ("netsh interface ipv6 add address \"%s\" %s/%d"), | ||
181 | device_visible_name, address, prefix_len); | ||
138 | /* | 182 | /* |
139 | * Set the address | 183 | * Set the address |
140 | */ | 184 | */ |
185 | ret = execute_shellcommand (command); | ||
141 | 186 | ||
142 | /* | 187 | /* Did it work?*/ |
143 | * Get the flags | 188 | if (0 != ret) |
144 | */ | ||
145 | |||
146 | |||
147 | /* | ||
148 | * Add the UP and RUNNING flags | ||
149 | */ | ||
150 | |||
151 | |||
152 | if (0 != close (fd)) | ||
153 | { | 189 | { |
154 | fprintf (stderr, "close failed: %s\n", strerror (errno)); | 190 | _ftprintf (stderr, _T ("Setting IPv6 address failed: %s\n"), strerror (ret)); |
155 | exit (1); | 191 | exit (1); |
156 | } | 192 | } |
157 | } | 193 | } |
@@ -164,42 +200,28 @@ set_address6 (const char *address, unsigned long prefix_len) | |||
164 | * @param mask the netmask | 200 | * @param mask the netmask |
165 | */ | 201 | */ |
166 | static void | 202 | static void |
167 | set_address4 (const char *dev, const char *address, const char *mask) | 203 | set_address4 (const char *address, const char *mask) |
168 | { | 204 | { |
169 | int fd = -1; | 205 | int ret = EINVAL; |
170 | 206 | TCHAR command[LINE_LEN]; | |
171 | /* | ||
172 | * Parse the address | ||
173 | */ | ||
174 | 207 | ||
175 | /* | 208 | /* TODO: Check if address & prefix_len make sense*/ |
176 | * Set the address | ||
177 | */ | ||
178 | 209 | ||
179 | /* | 210 | /* |
180 | * Parse the netmask | 211 | * prepare the command |
181 | */ | 212 | */ |
182 | 213 | _sntprintf (command, LINE_LEN, | |
183 | 214 | _T ("netsh interface ipv4 add address \"%s\" %s %s"), | |
215 | device_visible_name, address, mask); | ||
184 | /* | 216 | /* |
185 | * Set the netmask | 217 | * Set the address |
186 | */ | ||
187 | |||
188 | |||
189 | /* | ||
190 | * Get the flags | ||
191 | */ | ||
192 | |||
193 | |||
194 | /* | ||
195 | * Add the UP and RUNNING flags | ||
196 | */ | 218 | */ |
219 | ret = execute_shellcommand (command); | ||
197 | 220 | ||
198 | 221 | /* Did it work?*/ | |
199 | if (0 != close (fd)) | 222 | if (0 != ret) |
200 | { | 223 | { |
201 | fprintf (stderr, "close failed: %s\n", strerror (errno)); | 224 | _ftprintf (stderr, _T ("Setting IPv4 address failed: %s\n"), strerror (ret)); |
202 | (void) close (fd); | ||
203 | exit (1); | 225 | exit (1); |
204 | } | 226 | } |
205 | } | 227 | } |
@@ -220,7 +242,7 @@ setup_interface () | |||
220 | */ | 242 | */ |
221 | TCHAR inf_file_path[MAX_PATH]; | 243 | TCHAR inf_file_path[MAX_PATH]; |
222 | TCHAR hwidlist[LINE_LEN + 4]; | 244 | TCHAR hwidlist[LINE_LEN + 4]; |
223 | 245 | ||
224 | int str_lenth = 0; | 246 | int str_lenth = 0; |
225 | 247 | ||
226 | 248 | ||
@@ -238,9 +260,9 @@ setup_interface () | |||
238 | * | 260 | * |
239 | * A HWID list is double-\0 terminated and \0 separated | 261 | * A HWID list is double-\0 terminated and \0 separated |
240 | */ | 262 | */ |
241 | str_lenth = _tcslen (hwidlist) + 1 ; | 263 | str_lenth = _tcslen (hwidlist) + 1; |
242 | _tcsncpy (&hwidlist[str_lenth], secondary_hwid, LINE_LEN - str_lenth); | 264 | _tcsncpy (&hwidlist[str_lenth], secondary_hwid, LINE_LEN - str_lenth); |
243 | 265 | ||
244 | /** | 266 | /** |
245 | * Locate the inf-file, we need to store it somewhere where the system can | 267 | * Locate the inf-file, we need to store it somewhere where the system can |
246 | * find it. A good choice would be CWD/PDW or %WINDIR$\system32\ | 268 | * find it. A good choice would be CWD/PDW or %WINDIR$\system32\ |
@@ -257,44 +279,43 @@ setup_interface () | |||
257 | &guid, | 279 | &guid, |
258 | class, sizeof (class) / sizeof (TCHAR), | 280 | class, sizeof (class) / sizeof (TCHAR), |
259 | NULL)) | 281 | NULL)) |
260 | return FALSE; | 282 | return FALSE; |
261 | 283 | ||
262 | /** | 284 | /** |
263 | * Collect all the other needed information... | 285 | * Collect all the other needed information... |
264 | * let the system fill our this form | 286 | * let the system fill our this form |
265 | */ | 287 | */ |
266 | DeviceInfo = SetupDiCreateDeviceInfoList (&guid, NULL); | 288 | DeviceInfo = SetupDiCreateDeviceInfoList (&guid, NULL); |
267 | if (DeviceInfo == INVALID_HANDLE_VALUE) | 289 | if (DeviceInfo == INVALID_HANDLE_VALUE) |
268 | return FALSE; | 290 | return FALSE; |
269 | 291 | ||
270 | DeviceNode.cbSize = sizeof (SP_DEVINFO_DATA); | 292 | DeviceNode.cbSize = sizeof (SP_DEVINFO_DATA); |
271 | if (! SetupDiCreateDeviceInfo (DeviceInfo, | 293 | if (!SetupDiCreateDeviceInfo (DeviceInfo, |
272 | class, | 294 | class, |
273 | &guid, | 295 | &guid, |
274 | NULL, | 296 | NULL, |
275 | NULL, | 297 | NULL, |
276 | DICD_GENERATE_ID, | 298 | DICD_GENERATE_ID, |
277 | &DeviceNode)) | 299 | &DeviceNode)) |
278 | return FALSE; | 300 | return FALSE; |
279 | 301 | ||
280 | /* Deploy all the information collected into the registry */ | 302 | /* Deploy all the information collected into the registry */ |
281 | if (!SetupDiSetDeviceRegistryProperty (DeviceInfo, | 303 | if (!SetupDiSetDeviceRegistryProperty (DeviceInfo, |
282 | &DeviceNode, | 304 | &DeviceNode, |
283 | SPDRP_HARDWAREID, | 305 | SPDRP_HARDWAREID, |
284 | (LPBYTE) hwidlist, | 306 | (LPBYTE) hwidlist, |
285 | (lstrlen (hwidlist) + 2) * sizeof (TCHAR))) | 307 | (lstrlen (hwidlist) + 2) * sizeof (TCHAR))) |
286 | return FALSE; | 308 | return FALSE; |
287 | 309 | ||
288 | /* Install our new class(=device) into the system */ | 310 | /* Install our new class(=device) into the system */ |
289 | if (! SetupDiCallClassInstaller (DIF_REGISTERDEVICE, | 311 | if (!SetupDiCallClassInstaller (DIF_REGISTERDEVICE, |
290 | DeviceInfo, | 312 | DeviceInfo, |
291 | &DeviceNode)) | 313 | &DeviceNode)) |
292 | return FALSE; | 314 | return FALSE; |
293 | 315 | ||
294 | return TRUE; | 316 | return TRUE; |
295 | } | 317 | } |
296 | 318 | ||
297 | |||
298 | /** | 319 | /** |
299 | * Remove our new virtual interface to use for tunneling. | 320 | * Remove our new virtual interface to use for tunneling. |
300 | * This function must be called AFTER setup_interface! | 321 | * This function must be called AFTER setup_interface! |
@@ -305,10 +326,10 @@ static boolean | |||
305 | remove_interface () | 326 | remove_interface () |
306 | { | 327 | { |
307 | SP_REMOVEDEVICE_PARAMS remove; | 328 | SP_REMOVEDEVICE_PARAMS remove; |
308 | 329 | ||
309 | if (INVALID_HANDLE_VALUE == DeviceInfo) | 330 | if (INVALID_HANDLE_VALUE == DeviceInfo) |
310 | return FALSE; | 331 | return FALSE; |
311 | 332 | ||
312 | remove.ClassInstallHeader.cbSize = sizeof (SP_CLASSINSTALL_HEADER); | 333 | remove.ClassInstallHeader.cbSize = sizeof (SP_CLASSINSTALL_HEADER); |
313 | remove.HwProfile = 0; | 334 | remove.HwProfile = 0; |
314 | remove.Scope = DI_REMOVEDEVICE_GLOBAL; | 335 | remove.Scope = DI_REMOVEDEVICE_GLOBAL; |
@@ -317,21 +338,21 @@ remove_interface () | |||
317 | * 1. Prepare our existing device information set, and place the | 338 | * 1. Prepare our existing device information set, and place the |
318 | * uninstall related information into the structure | 339 | * uninstall related information into the structure |
319 | */ | 340 | */ |
320 | if (! SetupDiSetClassInstallParams (DeviceInfo, | 341 | if (!SetupDiSetClassInstallParams (DeviceInfo, |
321 | (PSP_DEVINFO_DATA) &DeviceNode, | 342 | (PSP_DEVINFO_DATA) & DeviceNode, |
322 | &remove.ClassInstallHeader, | 343 | &remove.ClassInstallHeader, |
323 | sizeof (remove))) | 344 | sizeof (remove))) |
324 | return FALSE; | 345 | return FALSE; |
325 | /* | 346 | /* |
326 | * 2. Uninstall the virtual interface using the class installer | 347 | * 2. Uninstall the virtual interface using the class installer |
327 | */ | 348 | */ |
328 | if (! SetupDiCallClassInstaller (DIF_REMOVE, | 349 | if (!SetupDiCallClassInstaller (DIF_REMOVE, |
329 | DeviceInfo, | 350 | DeviceInfo, |
330 | (PSP_DEVINFO_DATA) &DeviceNode)) | 351 | (PSP_DEVINFO_DATA) & DeviceNode)) |
331 | return FALSE; | 352 | return FALSE; |
332 | 353 | ||
333 | SetupDiDestroyDeviceInfoList(DeviceInfo); | 354 | SetupDiDestroyDeviceInfoList (DeviceInfo); |
334 | 355 | ||
335 | return TRUE; | 356 | return TRUE; |
336 | } | 357 | } |
337 | 358 | ||
@@ -351,7 +372,7 @@ resolve_interface_name () | |||
351 | LONG status; | 372 | LONG status; |
352 | DWORD len; | 373 | DWORD len; |
353 | int i = 0; | 374 | int i = 0; |
354 | boolean retval=FALSE; | 375 | boolean retval = FALSE; |
355 | TCHAR adapter[] = _T (INTERFACE_REGISTRY_LOCATION); | 376 | TCHAR adapter[] = _T (INTERFACE_REGISTRY_LOCATION); |
356 | 377 | ||
357 | /* We can obtain the PNP instance ID from our setupapi handle */ | 378 | /* We can obtain the PNP instance ID from our setupapi handle */ |
@@ -380,9 +401,9 @@ resolve_interface_name () | |||
380 | TCHAR instance_key[256]; | 401 | TCHAR instance_key[256]; |
381 | TCHAR query_key [256]; | 402 | TCHAR query_key [256]; |
382 | HKEY instance_key_handle; | 403 | HKEY instance_key_handle; |
383 | TCHAR pnpinstanceid_name[] = _T("PnpInstanceID"); | 404 | TCHAR pnpinstanceid_name[] = _T ("PnpInstanceID"); |
384 | TCHAR pnpinstanceid_value[256]; | 405 | TCHAR pnpinstanceid_value[256]; |
385 | TCHAR adaptername_name[] = _T("Name"); | 406 | TCHAR adaptername_name[] = _T ("Name"); |
386 | DWORD data_type; | 407 | DWORD data_type; |
387 | 408 | ||
388 | len = sizeof (adapter_key_handle); | 409 | len = sizeof (adapter_key_handle); |
@@ -407,8 +428,8 @@ resolve_interface_name () | |||
407 | 428 | ||
408 | /* prepare our new querty string: */ | 429 | /* prepare our new querty string: */ |
409 | _sntprintf (query_key, 256, _T ("%s\\%s\\Connection"), | 430 | _sntprintf (query_key, 256, _T ("%s\\%s\\Connection"), |
410 | _T (INTERFACE_REGISTRY_LOCATION), | 431 | _T (INTERFACE_REGISTRY_LOCATION), |
411 | instance_key); | 432 | instance_key); |
412 | 433 | ||
413 | /* look inside instance_key\\Connection */ | 434 | /* look inside instance_key\\Connection */ |
414 | status = RegOpenKeyEx ( | 435 | status = RegOpenKeyEx ( |
@@ -420,7 +441,7 @@ resolve_interface_name () | |||
420 | 441 | ||
421 | if (status != ERROR_SUCCESS) | 442 | if (status != ERROR_SUCCESS) |
422 | continue; | 443 | continue; |
423 | 444 | ||
424 | /* now, read our PnpInstanceID */ | 445 | /* now, read our PnpInstanceID */ |
425 | len = sizeof (pnpinstanceid_value); | 446 | len = sizeof (pnpinstanceid_value); |
426 | status = RegQueryValueEx (instance_key_handle, | 447 | status = RegQueryValueEx (instance_key_handle, |
@@ -432,12 +453,12 @@ resolve_interface_name () | |||
432 | 453 | ||
433 | if (status != ERROR_SUCCESS || data_type != REG_SZ) | 454 | if (status != ERROR_SUCCESS || data_type != REG_SZ) |
434 | goto cleanup; | 455 | goto cleanup; |
435 | 456 | ||
436 | /* compare the value we got to our devices PNPInstanceID*/ | 457 | /* compare the value we got to our devices PNPInstanceID*/ |
437 | if ( 0 != _tcsncmp (pnpinstanceid_value, pnp_instance_id, | 458 | if (0 != _tcsncmp (pnpinstanceid_value, pnp_instance_id, |
438 | sizeof (pnpinstanceid_value)/sizeof(TCHAR))) | 459 | sizeof (pnpinstanceid_value) / sizeof (TCHAR))) |
439 | goto cleanup; | 460 | goto cleanup; |
440 | 461 | ||
441 | len = sizeof (device_visible_name); | 462 | len = sizeof (device_visible_name); |
442 | status = RegQueryValueEx ( | 463 | status = RegQueryValueEx ( |
443 | instance_key_handle, | 464 | instance_key_handle, |
@@ -451,9 +472,9 @@ resolve_interface_name () | |||
451 | { | 472 | { |
452 | retval = TRUE; | 473 | retval = TRUE; |
453 | } | 474 | } |
454 | cleanup: | 475 | cleanup: |
455 | RegCloseKey (instance_key_handle); | 476 | RegCloseKey (instance_key_handle); |
456 | 477 | ||
457 | ++i; | 478 | ++i; |
458 | } | 479 | } |
459 | 480 | ||
@@ -472,7 +493,7 @@ resolve_interface_name () | |||
472 | static int | 493 | static int |
473 | init_tun (TCHAR *hwid) | 494 | init_tun (TCHAR *hwid) |
474 | { | 495 | { |
475 | int fd; | 496 | int fd=-1; |
476 | 497 | ||
477 | if (NULL == hwid) | 498 | if (NULL == hwid) |
478 | { | 499 | { |
@@ -480,17 +501,19 @@ init_tun (TCHAR *hwid) | |||
480 | return -1; | 501 | return -1; |
481 | } | 502 | } |
482 | 503 | ||
483 | if (! setup_interface()){ | 504 | if (!setup_interface ()) |
505 | { | ||
484 | errno = ENODEV; | 506 | errno = ENODEV; |
485 | return -1; | 507 | return -1; |
486 | } | 508 | } |
487 | 509 | ||
488 | if (! resolve_interface_name()){ | 510 | if (!resolve_interface_name ()) |
511 | { | ||
489 | errno = ENODEV; | 512 | errno = ENODEV; |
490 | return -1; | 513 | return -1; |
491 | } | 514 | } |
492 | 515 | ||
493 | 516 | ||
494 | return fd; | 517 | return fd; |
495 | } | 518 | } |
496 | 519 | ||
@@ -520,7 +543,6 @@ run (int fd_tun) | |||
520 | 543 | ||
521 | } | 544 | } |
522 | 545 | ||
523 | |||
524 | /** | 546 | /** |
525 | * Open VPN tunnel interface. | 547 | * Open VPN tunnel interface. |
526 | * | 548 | * |
@@ -539,24 +561,24 @@ main (int argc, char **argv) | |||
539 | TCHAR pid_as_string[LINE_LEN / 4]; | 561 | TCHAR pid_as_string[LINE_LEN / 4]; |
540 | int fd_tun; | 562 | int fd_tun; |
541 | int global_ret; | 563 | int global_ret; |
542 | 564 | ||
543 | if (6 != argc) | 565 | if (6 != argc) |
544 | { | 566 | { |
545 | fprintf (stderr, "Fatal: must supply 5 arguments!\n"); | 567 | fprintf (stderr, "Fatal: must supply 5 arguments!\n"); |
546 | return 1; | 568 | return 1; |
547 | } | 569 | } |
548 | 570 | ||
549 | strncpy (hwid, argv[1], LINE_LEN); | 571 | strncpy (hwid, argv[1], LINE_LEN); |
550 | hwid[LINE_LEN - 1] = _T('\0'); | 572 | hwid[LINE_LEN - 1] = _T ('\0'); |
551 | 573 | ||
552 | /* | 574 | /* |
553 | * We use our PID for finding/resolving the control-panel name of our virtual | 575 | * We use our PID for finding/resolving the control-panel name of our virtual |
554 | * device. PIDs are (of course) unique at runtime, thus we can safely use it | 576 | * device. PIDs are (of course) unique at runtime, thus we can safely use it |
555 | * as additional hardware-id for our device. | 577 | * as additional hardware-id for our device. |
556 | */ | 578 | */ |
557 | _itot(_getpid(), pid_as_string, 10); | 579 | _itot (_getpid (), pid_as_string, 10); |
558 | strncpy (secondary_hwid, hwid, LINE_LEN); | 580 | strncpy (secondary_hwid, hwid, LINE_LEN); |
559 | strncat (secondary_hwid, pid_as_string, LINE_LEN); | 581 | strncat (secondary_hwid, pid_as_string, LINE_LEN); |
560 | 582 | ||
561 | if (-1 == (fd_tun = init_tun (hwid))) | 583 | if (-1 == (fd_tun = init_tun (hwid))) |
562 | { | 584 | { |
@@ -577,7 +599,8 @@ main (int argc, char **argv) | |||
577 | if ((prefix_len < 1) || (prefix_len > 127)) | 599 | if ((prefix_len < 1) || (prefix_len > 127)) |
578 | { | 600 | { |
579 | fprintf (stderr, "Fatal: prefix_len out of range\n"); | 601 | fprintf (stderr, "Fatal: prefix_len out of range\n"); |
580 | return 1; | 602 | global_ret = -1; |
603 | goto cleanup; | ||
581 | } | 604 | } |
582 | 605 | ||
583 | set_address6 (address, prefix_len); | 606 | set_address6 (address, prefix_len); |
@@ -588,13 +611,10 @@ main (int argc, char **argv) | |||
588 | const char *address = argv[4]; | 611 | const char *address = argv[4]; |
589 | const char *mask = argv[5]; | 612 | const char *mask = argv[5]; |
590 | 613 | ||
591 | set_address4 (NULL, address, mask); | 614 | set_address4 (address, mask); |
592 | } | ||
593 | |||
594 | if (setup_interface ()) | ||
595 | { | ||
596 | ; | ||
597 | } | 615 | } |
616 | |||
617 | /*TODO: attach network interface! (need to research how that works with ovpn )*/ | ||
598 | 618 | ||
599 | /* | 619 | /* |
600 | uid_t uid = getuid (); | 620 | uid_t uid = getuid (); |
@@ -613,10 +633,10 @@ main (int argc, char **argv) | |||
613 | // no exit, we might as well die with SIGPIPE should it ever happen | 633 | // no exit, we might as well die with SIGPIPE should it ever happen |
614 | } | 634 | } |
615 | */ | 635 | */ |
616 | //run (fd_tun); | 636 | run (fd_tun); |
617 | global_ret = 0; | 637 | global_ret = 0; |
618 | cleanup: | 638 | cleanup: |
619 | remove_interface(); | 639 | remove_interface (); |
620 | 640 | ||
621 | return global_ret; | 641 | return global_ret; |
622 | } | 642 | } |