diff options
author | Christian Fuchs <christian.fuchs@cfuchs.net> | 2013-01-16 17:21:37 +0000 |
---|---|---|
committer | Christian Fuchs <christian.fuchs@cfuchs.net> | 2013-01-16 17:21:37 +0000 |
commit | bdee53dd2cb760e9acd601e251ba59c42c98c02f (patch) | |
tree | 484154f4edfe3ae8ce89219bed8c84824913d81d /src | |
parent | a98bf7b88926295d9c0c823a60c0cf7b8a981871 (diff) | |
download | gnunet-bdee53dd2cb760e9acd601e251ba59c42c98c02f.tar.gz gnunet-bdee53dd2cb760e9acd601e251ba59c42c98c02f.zip |
more debugging work.
Registry is extremely slow at refreshing. inserted a makeshift sleep(5)
to avoid retrieving outdated interface-information.
added proper return-codes to set_address4/6
fixed incorrect string-length handling for the HWID tags
updatedriverforplugandplaydevicesa now updates only the driver for our
current device, no longer the other siblings too (for >10 devices,
this could easily have taken > 60 seconds! ).
removed inet_pton, as we require API version XPSP2 anyway.
Diffstat (limited to 'src')
-rw-r--r-- | src/vpn/gnunet-helper-vpn-windows.c | 165 |
1 files changed, 57 insertions, 108 deletions
diff --git a/src/vpn/gnunet-helper-vpn-windows.c b/src/vpn/gnunet-helper-vpn-windows.c index dffe92cce..9d4657354 100644 --- a/src/vpn/gnunet-helper-vpn-windows.c +++ b/src/vpn/gnunet-helper-vpn-windows.c | |||
@@ -39,7 +39,6 @@ | |||
39 | #include <Winsock2.h> | 39 | #include <Winsock2.h> |
40 | #include "platform.h" | 40 | #include "platform.h" |
41 | #include "tap-windows.h" | 41 | #include "tap-windows.h" |
42 | |||
43 | /** | 42 | /** |
44 | * Need 'struct GNUNET_MessageHeader'. | 43 | * Need 'struct GNUNET_MessageHeader'. |
45 | */ | 44 | */ |
@@ -100,7 +99,6 @@ | |||
100 | 99 | ||
101 | /** | 100 | /** |
102 | * Location of the network interface list resides in registry. | 101 | * Location of the network interface list resides in registry. |
103 | * TODO: is this fixed on all version of windows? Checked with XP and 7 | ||
104 | */ | 102 | */ |
105 | #define INTERFACE_REGISTRY_LOCATION "SYSTEM\\CurrentControlSet\\Control\\Network\\{4D36E972-E325-11CE-BFC1-08002BE10318}" | 103 | #define INTERFACE_REGISTRY_LOCATION "SYSTEM\\CurrentControlSet\\Control\\Network\\{4D36E972-E325-11CE-BFC1-08002BE10318}" |
106 | 104 | ||
@@ -138,8 +136,6 @@ static SP_DEVINFO_DATA DeviceNode; | |||
138 | */ | 136 | */ |
139 | static char device_guid[256]; | 137 | static char device_guid[256]; |
140 | 138 | ||
141 | /* Overlapped IO Begins here (warning: nasty!) */ | ||
142 | |||
143 | /** | 139 | /** |
144 | * A IO Object + read/writebuffer + buffer-size for windows asynchronous IO handling | 140 | * A IO Object + read/writebuffer + buffer-size for windows asynchronous IO handling |
145 | */ | 141 | */ |
@@ -167,46 +163,8 @@ struct io_facility | |||
167 | 163 | ||
168 | /** | 164 | /** |
169 | * ReOpenFile is only available as of XP SP2 and 2003 SP1 | 165 | * ReOpenFile is only available as of XP SP2 and 2003 SP1 |
170 | */ | ||
171 | WINBASEAPI HANDLE WINAPI ReOpenFile (HANDLE, DWORD, DWORD, DWORD); | ||
172 | |||
173 | /** | ||
174 | * inet_pton() wrapper for WSAStringToAddress() | ||
175 | * | ||
176 | * this is needed as long as we support WinXP, because only Vista+ support | ||
177 | * inet_pton at all, and mingw does not yet offer inet_pton/ntop at all | ||
178 | * | ||
179 | * @param af - IN - the aftype this address is supposed to be (v4/v6) | ||
180 | * @param src - IN - the presentation form of the address | ||
181 | * @param dst - OUT - the numerical form of the address | ||
182 | * @return 0 on success, 1 on failure | ||
183 | */ | 166 | */ |
184 | int | 167 | WINBASEAPI HANDLE WINAPI ReOpenFile (HANDLE, DWORD, DWORD, DWORD); |
185 | inet_pton (int af, const char *src, void *dst) | ||
186 | { | ||
187 | struct sockaddr_storage addr; | ||
188 | int size = sizeof (addr); | ||
189 | char local_copy[INET6_ADDRSTRLEN + 1]; | ||
190 | |||
191 | ZeroMemory (&addr, sizeof (addr)); | ||
192 | /* stupid non-const API */ | ||
193 | strncpy (local_copy, src, INET6_ADDRSTRLEN + 1); | ||
194 | local_copy[INET6_ADDRSTRLEN] = 0; | ||
195 | |||
196 | if (WSAStringToAddressA (local_copy, af, NULL, (struct sockaddr *) &addr, &size) == 0) | ||
197 | { | ||
198 | switch (af) | ||
199 | { | ||
200 | case AF_INET: | ||
201 | *(struct in_addr *) dst = ((struct sockaddr_in *) &addr)->sin_addr; | ||
202 | return 1; | ||
203 | case AF_INET6: | ||
204 | *(struct in6_addr *) dst = ((struct sockaddr_in6 *) &addr)->sin6_addr; | ||
205 | return 1; | ||
206 | } | ||
207 | } | ||
208 | return 0; | ||
209 | } | ||
210 | 168 | ||
211 | /** | 169 | /** |
212 | * Wrapper for executing a shellcommand in windows. | 170 | * Wrapper for executing a shellcommand in windows. |
@@ -226,18 +184,11 @@ execute_shellcommand (char * command) | |||
226 | return EINVAL; | 184 | return EINVAL; |
227 | 185 | ||
228 | #ifdef TESTING | 186 | #ifdef TESTING |
229 | { | 187 | char output[LINE_LEN]; |
230 | char output[LINE_LEN]; | 188 | while (NULL != fgets (output, sizeof (output), pipe)) |
231 | 189 | printf (output); | |
232 | printf ("executed command: %s", command); | ||
233 | while (NULL != fgets (output, sizeof (output), pipe)) | ||
234 | printf (output); | ||
235 | } | ||
236 | #endif | 190 | #endif |
237 | 191 | ||
238 | if (!feof (pipe)) | ||
239 | return EPIPE; | ||
240 | |||
241 | return _pclose (pipe); | 192 | return _pclose (pipe); |
242 | } | 193 | } |
243 | 194 | ||
@@ -247,7 +198,7 @@ execute_shellcommand (char * command) | |||
247 | * @param address the IPv6-Address | 198 | * @param address the IPv6-Address |
248 | * @param prefix_len the length of the network-prefix | 199 | * @param prefix_len the length of the network-prefix |
249 | */ | 200 | */ |
250 | static void | 201 | static int |
251 | set_address6 (const char *address, unsigned long prefix_len) | 202 | set_address6 (const char *address, unsigned long prefix_len) |
252 | { | 203 | { |
253 | int ret = EINVAL; | 204 | int ret = EINVAL; |
@@ -263,7 +214,7 @@ set_address6 (const char *address, unsigned long prefix_len) | |||
263 | { | 214 | { |
264 | fprintf (stderr, "Failed to parse address `%s': %s\n", address, | 215 | fprintf (stderr, "Failed to parse address `%s': %s\n", address, |
265 | strerror (errno)); | 216 | strerror (errno)); |
266 | exit (1); | 217 | return -1; |
267 | } | 218 | } |
268 | 219 | ||
269 | /* | 220 | /* |
@@ -279,10 +230,8 @@ set_address6 (const char *address, unsigned long prefix_len) | |||
279 | 230 | ||
280 | /* Did it work?*/ | 231 | /* Did it work?*/ |
281 | if (0 != ret) | 232 | if (0 != ret) |
282 | { | 233 | fprintf (stderr, "Setting IPv6 address failed: %s\n", strerror (ret)); |
283 | fprintf (stderr, "Setting IPv6 address failed: %s\n", strerror (ret)); | 234 | return ret; |
284 | exit (1); // FIXME: return error code, shut down interface / unload driver | ||
285 | } | ||
286 | } | 235 | } |
287 | 236 | ||
288 | /** | 237 | /** |
@@ -292,7 +241,7 @@ set_address6 (const char *address, unsigned long prefix_len) | |||
292 | * @param address the IPv4-Address | 241 | * @param address the IPv4-Address |
293 | * @param mask the netmask | 242 | * @param mask the netmask |
294 | */ | 243 | */ |
295 | static void | 244 | static int |
296 | set_address4 (const char *address, const char *mask) | 245 | set_address4 (const char *address, const char *mask) |
297 | { | 246 | { |
298 | int ret = EINVAL; | 247 | int ret = EINVAL; |
@@ -308,13 +257,11 @@ set_address4 (const char *address, const char *mask) | |||
308 | { | 257 | { |
309 | fprintf (stderr, "Failed to parse address `%s': %s\n", address, | 258 | fprintf (stderr, "Failed to parse address `%s': %s\n", address, |
310 | strerror (errno)); | 259 | strerror (errno)); |
311 | exit (1); | 260 | return -1; |
312 | } | 261 | } |
313 | |||
314 | // Set Device to Subnet-Mode? | 262 | // Set Device to Subnet-Mode? |
315 | // do we really need tun.c:2925 ? | 263 | // do we really need tun.c:2925 ? |
316 | 264 | ||
317 | |||
318 | /* | 265 | /* |
319 | * prepare the command | 266 | * prepare the command |
320 | */ | 267 | */ |
@@ -328,10 +275,8 @@ set_address4 (const char *address, const char *mask) | |||
328 | 275 | ||
329 | /* Did it work?*/ | 276 | /* Did it work?*/ |
330 | if (0 != ret) | 277 | if (0 != ret) |
331 | { | 278 | fprintf (stderr, "Setting IPv4 address failed: %s\n", strerror (ret)); |
332 | fprintf (stderr, "Setting IPv4 address failed: %s\n", strerror (ret)); | 279 | return ret; |
333 | exit (1); // FIXME: return error code, shut down interface / unload driver | ||
334 | } | ||
335 | } | 280 | } |
336 | 281 | ||
337 | /** | 282 | /** |
@@ -353,14 +298,11 @@ setup_interface () | |||
353 | char hwidlist[LINE_LEN + 4]; | 298 | char hwidlist[LINE_LEN + 4]; |
354 | char class_name[128]; | 299 | char class_name[128]; |
355 | GUID class_guid; | 300 | GUID class_guid; |
356 | int str_lenth = 0; | 301 | int str_length = 0; |
357 | 302 | ||
358 | /** | 303 | /** |
359 | * Set the device's hardware ID and add it to a list. | 304 | * Set the device's hardware ID and add it to a list. |
360 | * This information will later on identify this device in registry. | 305 | * This information will later on identify this device in registry. |
361 | * | ||
362 | * TODO: Currently we just use TAP0901 as HWID, | ||
363 | * but we might want to add additional information | ||
364 | */ | 306 | */ |
365 | strncpy (hwidlist, HARDWARE_ID, LINE_LEN); | 307 | strncpy (hwidlist, HARDWARE_ID, LINE_LEN); |
366 | /** | 308 | /** |
@@ -369,9 +311,10 @@ setup_interface () | |||
369 | * | 311 | * |
370 | * A HWID list is double-\0 terminated and \0 separated | 312 | * A HWID list is double-\0 terminated and \0 separated |
371 | */ | 313 | */ |
372 | str_lenth = strlen (hwidlist) + 1; | 314 | str_length = strlen (hwidlist) + 1; |
373 | strncpy (&hwidlist[str_lenth], secondary_hwid, LINE_LEN - str_lenth); | 315 | strncpy (&hwidlist[str_length], secondary_hwid, LINE_LEN); |
374 | 316 | str_length += strlen (&hwidlist[str_length]) + 1; | |
317 | |||
375 | /** | 318 | /** |
376 | * Locate the inf-file, we need to store it somewhere where the system can | 319 | * Locate the inf-file, we need to store it somewhere where the system can |
377 | * find it. A good choice would be CWD/PDW or %WINDIR$\system32\ | 320 | * find it. A good choice would be CWD/PDW or %WINDIR$\system32\ |
@@ -380,7 +323,7 @@ setup_interface () | |||
380 | * We need to use a different driver for amd64/i386 ! | 323 | * We need to use a different driver for amd64/i386 ! |
381 | */ | 324 | */ |
382 | GetFullPathNameA (INF_FILE, MAX_PATH, inf_file_path, &temp_inf_filename); | 325 | GetFullPathNameA (INF_FILE, MAX_PATH, inf_file_path, &temp_inf_filename); |
383 | 326 | ||
384 | /** | 327 | /** |
385 | * Bootstrap our device info using the drivers inf-file | 328 | * Bootstrap our device info using the drivers inf-file |
386 | */ | 329 | */ |
@@ -389,7 +332,7 @@ setup_interface () | |||
389 | class_name, sizeof (class_name) / sizeof (char), | 332 | class_name, sizeof (class_name) / sizeof (char), |
390 | NULL)) | 333 | NULL)) |
391 | return FALSE; | 334 | return FALSE; |
392 | 335 | ||
393 | /** | 336 | /** |
394 | * Collect all the other needed information... | 337 | * Collect all the other needed information... |
395 | * let the system fill our this form | 338 | * let the system fill our this form |
@@ -397,7 +340,7 @@ setup_interface () | |||
397 | DeviceInfo = SetupDiCreateDeviceInfoList (&class_guid, NULL); | 340 | DeviceInfo = SetupDiCreateDeviceInfoList (&class_guid, NULL); |
398 | if (DeviceInfo == INVALID_HANDLE_VALUE) | 341 | if (DeviceInfo == INVALID_HANDLE_VALUE) |
399 | return FALSE; | 342 | return FALSE; |
400 | 343 | ||
401 | DeviceNode.cbSize = sizeof (SP_DEVINFO_DATA); | 344 | DeviceNode.cbSize = sizeof (SP_DEVINFO_DATA); |
402 | if (!SetupDiCreateDeviceInfoA (DeviceInfo, | 345 | if (!SetupDiCreateDeviceInfoA (DeviceInfo, |
403 | class_name, | 346 | class_name, |
@@ -407,28 +350,28 @@ setup_interface () | |||
407 | DICD_GENERATE_ID, | 350 | DICD_GENERATE_ID, |
408 | &DeviceNode)) | 351 | &DeviceNode)) |
409 | return FALSE; | 352 | return FALSE; |
410 | 353 | ||
411 | /* Deploy all the information collected into the registry */ | 354 | /* Deploy all the information collected into the registry */ |
412 | if (!SetupDiSetDeviceRegistryPropertyA (DeviceInfo, | 355 | if (!SetupDiSetDeviceRegistryPropertyA (DeviceInfo, |
413 | &DeviceNode, | 356 | &DeviceNode, |
414 | SPDRP_HARDWAREID, | 357 | SPDRP_HARDWAREID, |
415 | (LPBYTE) hwidlist, | 358 | (LPBYTE) hwidlist, |
416 | (lstrlenA (hwidlist) + 2) * sizeof (char))) | 359 | str_length * sizeof (char))) |
417 | return FALSE; | 360 | return FALSE; |
418 | 361 | ||
419 | /* Install our new class(=device) into the system */ | 362 | /* Install our new class(=device) into the system */ |
420 | if (!SetupDiCallClassInstaller (DIF_REGISTERDEVICE, | 363 | if (!SetupDiCallClassInstaller (DIF_REGISTERDEVICE, |
421 | DeviceInfo, | 364 | DeviceInfo, |
422 | &DeviceNode)) | 365 | &DeviceNode)) |
423 | return FALSE; | 366 | return FALSE; |
424 | 367 | ||
425 | if(!UpdateDriverForPlugAndPlayDevicesA(NULL, | 368 | if (!UpdateDriverForPlugAndPlayDevicesA (NULL, |
426 | HARDWARE_ID, // I can haz secondary HWID too? | 369 | secondary_hwid, |
427 | inf_file_path, | 370 | inf_file_path, |
428 | INSTALLFLAG_FORCE | INSTALLFLAG_NONINTERACTIVE, | 371 | INSTALLFLAG_FORCE | INSTALLFLAG_NONINTERACTIVE, |
429 | NULL)) //reboot required? NEVER! | 372 | NULL)) //reboot required? NEVER! |
430 | return FALSE; | 373 | return FALSE; |
431 | 374 | ||
432 | return TRUE; | 375 | return TRUE; |
433 | } | 376 | } |
434 | 377 | ||
@@ -491,6 +434,9 @@ resolve_interface_name () | |||
491 | boolean retval = FALSE; | 434 | boolean retval = FALSE; |
492 | char adapter[] = INTERFACE_REGISTRY_LOCATION; | 435 | char adapter[] = INTERFACE_REGISTRY_LOCATION; |
493 | 436 | ||
437 | /* Registry is incredibly slow, wait a few seconds for it to refresh */ | ||
438 | sleep (5); | ||
439 | |||
494 | /* We can obtain the PNP instance ID from our setupapi handle */ | 440 | /* We can obtain the PNP instance ID from our setupapi handle */ |
495 | device_details.cbSize = sizeof (device_details); | 441 | device_details.cbSize = sizeof (device_details); |
496 | if (CR_SUCCESS != CM_Get_Device_ID_ExA (DeviceNode.DevInst, | 442 | if (CR_SUCCESS != CM_Get_Device_ID_ExA (DeviceNode.DevInst, |
@@ -499,7 +445,7 @@ resolve_interface_name () | |||
499 | 0, //must be 0 | 445 | 0, //must be 0 |
500 | NULL)) //hMachine, we are local | 446 | NULL)) //hMachine, we are local |
501 | return FALSE; | 447 | return FALSE; |
502 | 448 | ||
503 | /* Now we can use this ID to locate the correct networks interface in registry */ | 449 | /* Now we can use this ID to locate the correct networks interface in registry */ |
504 | if (ERROR_SUCCESS != RegOpenKeyExA ( | 450 | if (ERROR_SUCCESS != RegOpenKeyExA ( |
505 | HKEY_LOCAL_MACHINE, | 451 | HKEY_LOCAL_MACHINE, |
@@ -521,8 +467,8 @@ resolve_interface_name () | |||
521 | char pnpinstanceid_value[256]; | 467 | char pnpinstanceid_value[256]; |
522 | char adaptername_name[] = "Name"; | 468 | char adaptername_name[] = "Name"; |
523 | DWORD data_type; | 469 | DWORD data_type; |
524 | 470 | ||
525 | len = 256 * sizeof(char); | 471 | len = 256 * sizeof (char); |
526 | /* optain a subkey of {4D36E972-E325-11CE-BFC1-08002BE10318} */ | 472 | /* optain a subkey of {4D36E972-E325-11CE-BFC1-08002BE10318} */ |
527 | status = RegEnumKeyExA ( | 473 | status = RegEnumKeyExA ( |
528 | adapter_key_handle, | 474 | adapter_key_handle, |
@@ -533,7 +479,7 @@ resolve_interface_name () | |||
533 | NULL, | 479 | NULL, |
534 | NULL, | 480 | NULL, |
535 | NULL); | 481 | NULL); |
536 | 482 | ||
537 | /* this may fail due to one of two reasons: | 483 | /* this may fail due to one of two reasons: |
538 | * we are at the end of the list*/ | 484 | * we are at the end of the list*/ |
539 | if (ERROR_NO_MORE_ITEMS == status) | 485 | if (ERROR_NO_MORE_ITEMS == status) |
@@ -541,10 +487,10 @@ resolve_interface_name () | |||
541 | // * we found a broken registry key, continue with the next key. | 487 | // * we found a broken registry key, continue with the next key. |
542 | if (ERROR_SUCCESS != status) | 488 | if (ERROR_SUCCESS != status) |
543 | goto cleanup; | 489 | goto cleanup; |
544 | 490 | ||
545 | /* prepare our new query string: */ | 491 | /* prepare our new query string: */ |
546 | snprintf (query_key, 256, "%s\\%s\\Connection", | 492 | snprintf (query_key, 256, "%s\\%s\\Connection", |
547 | INTERFACE_REGISTRY_LOCATION, | 493 | adapter, |
548 | instance_key); | 494 | instance_key); |
549 | 495 | ||
550 | /* look inside instance_key\\Connection */ | 496 | /* look inside instance_key\\Connection */ |
@@ -594,15 +540,15 @@ resolve_interface_name () | |||
594 | 540 | ||
595 | strncpy (device_guid, instance_key, 256); | 541 | strncpy (device_guid, instance_key, 256); |
596 | retval = TRUE; | 542 | retval = TRUE; |
597 | 543 | ||
598 | cleanup: | 544 | cleanup: |
599 | RegCloseKey (instance_key_handle); | 545 | RegCloseKey (instance_key_handle); |
600 | 546 | ||
601 | ++i; | 547 | ++i; |
602 | } | 548 | } |
603 | 549 | ||
604 | RegCloseKey (adapter_key_handle); | 550 | RegCloseKey (adapter_key_handle); |
605 | 551 | ||
606 | return retval; | 552 | return retval; |
607 | } | 553 | } |
608 | 554 | ||
@@ -660,7 +606,7 @@ init_tun () | |||
660 | errno = ENODEV; | 606 | errno = ENODEV; |
661 | return INVALID_HANDLE_VALUE; | 607 | return INVALID_HANDLE_VALUE; |
662 | } | 608 | } |
663 | 609 | ||
664 | /* Open Windows TAP-Windows adapter */ | 610 | /* Open Windows TAP-Windows adapter */ |
665 | snprintf (device_path, sizeof (device_path), "%s%s%s", | 611 | snprintf (device_path, sizeof (device_path), "%s%s%s", |
666 | USERMODEDEVICEDIR, | 612 | USERMODEDEVICEDIR, |
@@ -682,14 +628,14 @@ init_tun () | |||
682 | fprintf (stderr, "CreateFile failed on TAP device: %s\n", device_path); | 628 | fprintf (stderr, "CreateFile failed on TAP device: %s\n", device_path); |
683 | return handle; | 629 | return handle; |
684 | } | 630 | } |
685 | 631 | ||
686 | /* get driver version info */ | 632 | /* get driver version info */ |
687 | if (!check_tapw32_version (handle)) | 633 | if (!check_tapw32_version (handle)) |
688 | { | 634 | { |
689 | CloseHandle (handle); | 635 | CloseHandle (handle); |
690 | return INVALID_HANDLE_VALUE; | 636 | return INVALID_HANDLE_VALUE; |
691 | } | 637 | } |
692 | 638 | ||
693 | /* TODO (opt?): get MTU-Size */ | 639 | /* TODO (opt?): get MTU-Size */ |
694 | 640 | ||
695 | return handle; | 641 | return handle; |
@@ -1104,7 +1050,7 @@ main (int argc, char **argv) | |||
1104 | { | 1050 | { |
1105 | char hwid[LINE_LEN]; | 1051 | char hwid[LINE_LEN]; |
1106 | HANDLE handle; | 1052 | HANDLE handle; |
1107 | int global_ret; | 1053 | int global_ret = 0; |
1108 | 1054 | ||
1109 | if (6 != argc) | 1055 | if (6 != argc) |
1110 | { | 1056 | { |
@@ -1123,7 +1069,7 @@ main (int argc, char **argv) | |||
1123 | snprintf (secondary_hwid, LINE_LEN / 2, "%s-%d", | 1069 | snprintf (secondary_hwid, LINE_LEN / 2, "%s-%d", |
1124 | hwid, | 1070 | hwid, |
1125 | _getpid ()); | 1071 | _getpid ()); |
1126 | 1072 | ||
1127 | if (INVALID_HANDLE_VALUE == (handle = init_tun ())) | 1073 | if (INVALID_HANDLE_VALUE == (handle = init_tun ())) |
1128 | { | 1074 | { |
1129 | fprintf (stderr, "Fatal: could not initialize virtual-interface %s with IPv6 %s/%s and IPv4 %s/%s\n", | 1075 | fprintf (stderr, "Fatal: could not initialize virtual-interface %s with IPv6 %s/%s and IPv4 %s/%s\n", |
@@ -1132,7 +1078,8 @@ main (int argc, char **argv) | |||
1132 | argv[3], | 1078 | argv[3], |
1133 | argv[4], | 1079 | argv[4], |
1134 | argv[5]); | 1080 | argv[5]); |
1135 | return 1; | 1081 | global_ret = -1; |
1082 | goto cleanup; | ||
1136 | } | 1083 | } |
1137 | 1084 | ||
1138 | if (0 != strcmp (argv[2], "-")) | 1085 | if (0 != strcmp (argv[2], "-")) |
@@ -1147,7 +1094,8 @@ main (int argc, char **argv) | |||
1147 | goto cleanup; | 1094 | goto cleanup; |
1148 | } | 1095 | } |
1149 | 1096 | ||
1150 | set_address6 (address, prefix_len); | 1097 | if (0 != (global_ret = set_address6 (address, prefix_len))) |
1098 | goto cleanup; | ||
1151 | } | 1099 | } |
1152 | 1100 | ||
1153 | if (0 != strcmp (argv[4], "-")) | 1101 | if (0 != strcmp (argv[4], "-")) |
@@ -1155,13 +1103,14 @@ main (int argc, char **argv) | |||
1155 | const char *address = argv[4]; | 1103 | const char *address = argv[4]; |
1156 | const char *mask = argv[5]; | 1104 | const char *mask = argv[5]; |
1157 | 1105 | ||
1158 | set_address4 (address, mask); | 1106 | if (0 != (global_ret = set_address4 (address, mask))) |
1107 | goto cleanup; | ||
1159 | } | 1108 | } |
1160 | 1109 | ||
1161 | run (handle); | 1110 | run (handle); |
1162 | global_ret = 0; | 1111 | global_ret = 0; |
1163 | cleanup: | 1112 | cleanup: |
1164 | remove_interface (); | ||
1165 | 1113 | ||
1114 | remove_interface (); | ||
1166 | return global_ret; | 1115 | return global_ret; |
1167 | } | 1116 | } |