From: Lev Stipakov Date: Fri, 14 Nov 2025 21:21:07 +0000 (+0100) Subject: tapctl: factor out command handlers X-Git-Tag: v2.7_rc2~16 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=ef4937f87280f68fb14459ca53d955c8d5d771e5;p=thirdparty%2Fopenvpn.git tapctl: factor out command handlers Change-Id: I432e07216f9adb8f767af172fa37b626b350f994 Signed-off-by: Lev Stipakov Acked-by: Gert Doering Gerrit URL: https://gerrit.openvpn.net/c/openvpn/+/1370 Message-Id: <20251114212112.6370-1-gert@greenie.muc.de> URL: https://www.mail-archive.com/openvpn-devel@lists.sourceforge.net/msg34432.html Signed-off-by: Gert Doering --- diff --git a/src/tapctl/main.c b/src/tapctl/main.c index 84da16119..4d259988c 100644 --- a/src/tapctl/main.c +++ b/src/tapctl/main.c @@ -201,262 +201,256 @@ get_unique_adapter_name(LPCWSTR hwid, struct tap_adapter_node *adapter_list) return NULL; } -/** - * Program entry point - */ -int __cdecl wmain(int argc, LPCWSTR argv[]) -{ - int iResult; - BOOL bRebootRequired = FALSE; +static int command_create(int argc, LPCWSTR argv[], BOOL *bRebootRequired); +static int command_list(int argc, LPCWSTR argv[]); +static int command_delete(int argc, LPCWSTR argv[], BOOL *bRebootRequired); - /* Ask SetupAPI to keep quiet. */ - SetupSetNonInteractiveMode(TRUE); - - if (argc < 2) - { - usage(); - return 1; - } - else if (wcsicmp(argv[1], L"help") == 0) +static int +command_create(int argc, LPCWSTR argv[], BOOL *bRebootRequired) +{ + LPCWSTR szName = NULL; + LPCWSTR szHwId = L"root\\" _L(TAP_WIN_COMPONENT_ID); + struct tap_adapter_node *adapter_list = NULL; + LPWSTR adapter_name = NULL; + LPOLESTR adapter_id = NULL; + GUID guidAdapter; + int result = 1; + + for (int i = 2; i < argc; i++) { - /* Output help. */ - if (argc < 3) - { - usage(); - } - else if (wcsicmp(argv[2], L"create") == 0) + if (wcsicmp(argv[i], L"--name") == 0) { - fwprintf(stderr, usage_message_create, title_string); + szName = argv[++i]; } - else if (wcsicmp(argv[2], L"list") == 0) + else if (wcsicmp(argv[i], L"--hwid") == 0) { - fwprintf(stderr, usage_message_list, title_string); - } - else if (wcsicmp(argv[2], L"delete") == 0) - { - fwprintf(stderr, usage_message_delete, title_string); + szHwId = argv[++i]; } else { fwprintf(stderr, - L"Unknown command \"%ls" - L"\". Please, use \"tapctl help\" to list supported commands.\n", - argv[2]); + L"Unknown option \"%ls" + L"\". Please, use \"tapctl help create\" to list supported options. Ignored.\n", + argv[i]); } + } - return 1; + DWORD dwResult = + tap_create_adapter(NULL, L"Virtual Ethernet", szHwId, bRebootRequired, &guidAdapter); + if (dwResult != ERROR_SUCCESS) + { + fwprintf(stderr, L"Creating TUN/TAP adapter failed (error 0x%x).\n", dwResult); + return result; } - else if (wcsicmp(argv[1], L"create") == 0) + + dwResult = tap_list_adapters(NULL, NULL, &adapter_list); + if (dwResult != ERROR_SUCCESS) { - LPCWSTR szName = NULL; - LPCWSTR szHwId = L"root\\" _L(TAP_WIN_COMPONENT_ID); + fwprintf(stderr, L"Enumerating adapters failed (error 0x%x).\n", dwResult); + tap_delete_adapter(NULL, &guidAdapter, bRebootRequired); + return result; + } - /* Parse options. */ - for (int i = 2; i < argc; i++) + adapter_name = szName ? wcsdup(szName) : get_unique_adapter_name(szHwId, adapter_list); + if (adapter_name) + { + if (szName && !is_adapter_name_available(adapter_name, adapter_list, TRUE)) { - if (wcsicmp(argv[i], L"--name") == 0) - { - szName = argv[++i]; - } - else if (wcsicmp(argv[i], L"--hwid") == 0) - { - szHwId = argv[++i]; - } - else - { - fwprintf( - stderr, - L"Unknown option \"%ls" - L"\". Please, use \"tapctl help create\" to list supported options. Ignored.\n", - argv[i]); - } + tap_delete_adapter(NULL, &guidAdapter, bRebootRequired); + goto cleanup; } - /* Create TUN/TAP adapter. */ - GUID guidAdapter; - LPOLESTR szAdapterId = NULL; - DWORD dwResult = - tap_create_adapter(NULL, L"Virtual Ethernet", szHwId, &bRebootRequired, &guidAdapter); + dwResult = tap_set_adapter_name(&guidAdapter, adapter_name, FALSE); if (dwResult != ERROR_SUCCESS) { - fwprintf(stderr, L"Creating TUN/TAP adapter failed (error 0x%x).\n", dwResult); - iResult = 1; - goto quit; + StringFromIID((REFIID)&guidAdapter, &adapter_id); + fwprintf(stderr, + L"Renaming TUN/TAP adapter %ls" + L" to \"%ls\" failed (error 0x%x).\n", + adapter_id, adapter_name, dwResult); + CoTaskMemFree(adapter_id); + goto cleanup; } + } - /* Get existing network adapters. */ - struct tap_adapter_node *pAdapterList = NULL; - dwResult = tap_list_adapters(NULL, NULL, &pAdapterList); - if (dwResult != ERROR_SUCCESS) - { - fwprintf(stderr, L"Enumerating adapters failed (error 0x%x).\n", dwResult); - iResult = 1; - goto create_delete_adapter; - } + result = 0; - LPWSTR adapter_name = - szName ? wcsdup(szName) : get_unique_adapter_name(szHwId, pAdapterList); - if (adapter_name) - { - /* Check for duplicates when name was specified, - * otherwise get_adapter_default_name() takes care of it */ - if (szName && !is_adapter_name_available(adapter_name, pAdapterList, TRUE)) - { - iResult = 1; - goto create_cleanup_pAdapterList; - } +cleanup: + free(adapter_name); + tap_free_adapter_list(adapter_list); - /* Rename the adapter. */ - dwResult = tap_set_adapter_name(&guidAdapter, adapter_name, FALSE); - if (dwResult != ERROR_SUCCESS) - { - StringFromIID((REFIID)&guidAdapter, &szAdapterId); - fwprintf(stderr, - L"Renaming TUN/TAP adapter %ls" - L" to \"%ls\" failed (error 0x%x).\n", - szAdapterId, adapter_name, dwResult); - CoTaskMemFree(szAdapterId); - iResult = 1; - goto quit; - } - } + if (result == 0) + { + StringFromIID((REFIID)&guidAdapter, &adapter_id); + fwprintf(stdout, L"%ls\n", adapter_id); + CoTaskMemFree(adapter_id); + } - iResult = 0; + return result; +} -create_cleanup_pAdapterList: - free(adapter_name); +static int +command_list(int argc, LPCWSTR argv[]) +{ + WCHAR szzHwId[0x100] = + L"root\\" _L(TAP_WIN_COMPONENT_ID) L"\0" _L(TAP_WIN_COMPONENT_ID) L"\0" + L"ovpn-dco\0"; - tap_free_adapter_list(pAdapterList); - if (iResult) + for (int i = 2; i < argc; i++) + { + if (wcsicmp(argv[i], L"--hwid") == 0) { - goto create_delete_adapter; + memset(szzHwId, 0, sizeof(szzHwId)); + ++i; + memcpy_s(szzHwId, + sizeof(szzHwId) - 2 * sizeof(WCHAR), + argv[i], wcslen(argv[i]) * sizeof(WCHAR)); } + else + { + fwprintf(stderr, + L"Unknown option \"%ls" + L"\". Please, use \"tapctl help list\" to list supported options. Ignored.\n", + argv[i]); + } + } - /* Output adapter GUID. */ - StringFromIID((REFIID)&guidAdapter, &szAdapterId); - fwprintf(stdout, L"%ls\n", szAdapterId); - CoTaskMemFree(szAdapterId); + struct tap_adapter_node *adapter_list = NULL; + DWORD dwResult = tap_list_adapters(NULL, szzHwId, &adapter_list); + if (dwResult != ERROR_SUCCESS) + { + fwprintf(stderr, L"Enumerating TUN/TAP adapters failed (error 0x%x).\n", dwResult); + return 1; + } - iResult = 0; - goto quit; + for (struct tap_adapter_node *adapter = adapter_list; adapter; adapter = adapter->pNext) + { + LPOLESTR adapter_id = NULL; + StringFromIID((REFIID)&adapter->guid, &adapter_id); + fwprintf(stdout, + L"%ls\t%" + L"ls\n", + adapter_id, adapter->szName); + CoTaskMemFree(adapter_id); + } -create_delete_adapter: - tap_delete_adapter(NULL, &guidAdapter, &bRebootRequired); - iResult = 1; - goto quit; + tap_free_adapter_list(adapter_list); + + return 0; +} + +static int +command_delete(int argc, LPCWSTR argv[], BOOL *bRebootRequired) +{ + if (argc < 3) + { + fwprintf(stderr, + L"Missing adapter GUID or name. Please, use \"tapctl help delete\" for usage info.\n"); + return 1; } - else if (wcsicmp(argv[1], L"list") == 0) + + GUID guidAdapter; + if (FAILED(IIDFromString(argv[2], (LPIID)&guidAdapter))) { - WCHAR szzHwId[0x100] = - L"root\\" _L(TAP_WIN_COMPONENT_ID) L"\0" _L(TAP_WIN_COMPONENT_ID) L"\0" - L"ovpn-dco\0"; + struct tap_adapter_node *adapter_list = NULL; + DWORD dwResult = tap_list_adapters(NULL, NULL, &adapter_list); + if (dwResult != ERROR_SUCCESS) + { + fwprintf(stderr, L"Enumerating TUN/TAP adapters failed (error 0x%x).\n", dwResult); + return 1; + } - /* Parse options. */ - for (int i = 2; i < argc; i++) + BOOL found = FALSE; + for (struct tap_adapter_node *adapter = adapter_list; adapter; adapter = adapter->pNext) { - if (wcsicmp(argv[i], L"--hwid") == 0) + if (wcsicmp(argv[2], adapter->szName) == 0) { - memset(szzHwId, 0, sizeof(szzHwId)); - ++i; - memcpy_s(szzHwId, - sizeof(szzHwId) - 2 * sizeof(WCHAR) /*requires double zero termination*/, - argv[i], wcslen(argv[i]) * sizeof(WCHAR)); - } - else - { - fwprintf( - stderr, - L"Unknown option \"%ls" - L"\". Please, use \"tapctl help list\" to list supported options. Ignored.\n", - argv[i]); + memcpy(&guidAdapter, &adapter->guid, sizeof(GUID)); + found = TRUE; + break; } } - /* Output list of adapters with given hardware ID. */ - struct tap_adapter_node *pAdapterList = NULL; - DWORD dwResult = tap_list_adapters(NULL, szzHwId, &pAdapterList); - if (dwResult != ERROR_SUCCESS) - { - fwprintf(stderr, L"Enumerating TUN/TAP adapters failed (error 0x%x).\n", dwResult); - iResult = 1; - goto quit; - } + tap_free_adapter_list(adapter_list); - for (struct tap_adapter_node *pAdapter = pAdapterList; pAdapter; pAdapter = pAdapter->pNext) + if (!found) { - LPOLESTR szAdapterId = NULL; - StringFromIID((REFIID)&pAdapter->guid, &szAdapterId); - fwprintf(stdout, - L"%ls\t%" - L"ls\n", - szAdapterId, pAdapter->szName); - CoTaskMemFree(szAdapterId); + fwprintf(stderr, L"\"%ls\" adapter not found.\n", argv[2]); + return 1; } + } - iResult = 0; - tap_free_adapter_list(pAdapterList); + DWORD dwResult = tap_delete_adapter(NULL, &guidAdapter, bRebootRequired); + if (dwResult != ERROR_SUCCESS) + { + fwprintf(stderr, + L"Deleting adapter \"%ls" + L"\" failed (error 0x%x).\n", + argv[2], dwResult); + return 1; } - else if (wcsicmp(argv[1], L"delete") == 0) + + return 0; +} + +/** + * Program entry point + */ +int __cdecl wmain(int argc, LPCWSTR argv[]) +{ + int iResult; + BOOL bRebootRequired = FALSE; + + /* Ask SetupAPI to keep quiet. */ + SetupSetNonInteractiveMode(TRUE); + + if (argc < 2) { + usage(); + return 1; + } + else if (wcsicmp(argv[1], L"help") == 0) + { + /* Output help. */ if (argc < 3) { - fwprintf( - stderr, - L"Missing adapter GUID or name. Please, use \"tapctl help delete\" for usage info.\n"); - return 1; + usage(); } - - GUID guidAdapter; - if (FAILED(IIDFromString(argv[2], (LPIID)&guidAdapter))) + else if (wcsicmp(argv[2], L"create") == 0) { - /* The argument failed to covert to GUID. Treat it as the adapter name. */ - struct tap_adapter_node *pAdapterList = NULL; - DWORD dwResult = tap_list_adapters(NULL, NULL, &pAdapterList); - if (dwResult != ERROR_SUCCESS) - { - fwprintf(stderr, L"Enumerating TUN/TAP adapters failed (error 0x%x).\n", dwResult); - iResult = 1; - goto quit; - } - - for (struct tap_adapter_node *pAdapter = pAdapterList;; pAdapter = pAdapter->pNext) - { - if (pAdapter == NULL) - { - fwprintf(stderr, L"\"%ls\" adapter not found.\n", argv[2]); - iResult = 1; - goto delete_cleanup_pAdapterList; - } - else if (wcsicmp(argv[2], pAdapter->szName) == 0) - { - memcpy(&guidAdapter, &pAdapter->guid, sizeof(GUID)); - break; - } - } - - iResult = 0; - -delete_cleanup_pAdapterList: - tap_free_adapter_list(pAdapterList); - if (iResult) - { - goto quit; - } + fwprintf(stderr, usage_message_create, title_string); } - - /* Delete the network adapter. */ - DWORD dwResult = tap_delete_adapter(NULL, &guidAdapter, &bRebootRequired); - if (dwResult != ERROR_SUCCESS) + else if (wcsicmp(argv[2], L"list") == 0) + { + fwprintf(stderr, usage_message_list, title_string); + } + else if (wcsicmp(argv[2], L"delete") == 0) + { + fwprintf(stderr, usage_message_delete, title_string); + } + else { fwprintf(stderr, - L"Deleting adapter \"%ls" - L"\" failed (error 0x%x).\n", - argv[2], dwResult); - iResult = 1; - goto quit; + L"Unknown command \"%ls" + L"\". Please, use \"tapctl help\" to list supported commands.\n", + argv[2]); } - iResult = 0; + return 1; + } + else if (wcsicmp(argv[1], L"create") == 0) + { + iResult = command_create(argc, argv, &bRebootRequired); + goto quit; + } + else if (wcsicmp(argv[1], L"list") == 0) + { + iResult = command_list(argc, argv); + goto quit; + } + else if (wcsicmp(argv[1], L"delete") == 0) + { + iResult = command_delete(argc, argv, &bRebootRequired); goto quit; } else