// Decompose combined name UINT Win32EthGetNameAndIdFromCombinedName(char *name, UINT name_size, char *str) { UINT ret = 0; char id_str[MAX_SIZE]; UINT len; // Validate arguments ClearStr(name, name_size); StrCpy(name, name_size, str); if (name == NULL || str == NULL) { return 0; } len = StrLen(str); if (len >= 16) { StrCpy(id_str, sizeof(id_str), str + len - 16); if (StartWith(id_str, " (ID=")) { if (EndWith(id_str, ")")) { char num[MAX_SIZE]; Zero(num, sizeof(num)); StrCpy(num, sizeof(num), id_str + 5); num[StrLen(num) - 1] = 0; ret = ToInt(num); if (ret != 0) { name[len - 16] = 0; } } } } return ret; }
// Check whether the command specified by the user is a abbreviation of existing commands bool IsOmissionName(char *input_name, char *real_name) { char oname[128]; // Validate arguments if (input_name == NULL || real_name == NULL) { return false; } if (IsAllUpperStr(real_name)) { // Command of all capital letters do not take abbreviations return false; } GetOmissionName(oname, sizeof(oname), real_name); if (IsEmptyStr(oname)) { return false; } if (StartWith(oname, input_name)) { // Example: The oname of AccountSecureCertSet is "ascs". // But if the user enters "asc", returns true return true; } if (StartWith(input_name, oname)) { // Example: When two commands AccountCreate and AccountConnect exist, // if the user enter "aconnect" , only AccountConnect is true if (EndWith(real_name, &input_name[StrLen(oname)])) { return true; } } return false; }
// main function int main(int argc, char *argv[]) { wchar_t *s; UINT ret = 0; #ifdef OS_WIN32 SetConsoleTitleA(CEDAR_PRODUCT_STR " VPN Command Line Utility"); #endif // OS_WIN32 InitMayaqua(false, false, argc, argv); InitCedar(); s = GetCommandLineUniStr(); if (s == NULL) { s = CopyUniStr(L""); } if (UniStrCmpi(s, L"exit") != 0) { UINT size = UniStrSize(s) + 64; wchar_t *tmp; tmp = Malloc(size); UniFormat(tmp, size, L"vpncmd %s", s); ret = CommandMain(tmp); Free(tmp); } #ifdef OS_WIN32 { UINT i; LIST *o = MsGetProcessList(); bool b = false; for (i = 0;i < LIST_NUM(o);i++) { MS_PROCESS *p = LIST_DATA(o, i); if (EndWith(p->ExeFilename, "\\cmd.exe") || EndWith(p->ExeFilename, "\\command.com")) { b = true; break; } } MsFreeProcessList(o); if (b == false) { if (ret != ERR_NO_ERROR) { SleepThread(1000); } } } #endif // OS_WIN32 Free(s); FreeCedar(); FreeMayaqua(); return ret; }
// Get VLAN tag pass-through availability of all devices bool EnumEthVLanWin32(RPC_ENUM_ETH_VLAN *t) { UINT i; LIST *o; // Validate arguments if (t == NULL) { return false; } Zero(t, sizeof(RPC_ENUM_ETH_VLAN)); if (MsIsWin2000OrGreater() == false) { return false; } if (IsEthSupported() == false) { return false; } // Get device list Lock(eth_list_lock); InitEthAdaptersList(); o = NewListFast(CmpRpcEnumEthVLan); for (i = 0;i < LIST_NUM(eth_list);i++) { WP_ADAPTER *a = LIST_DATA(eth_list, i); if (IsEmptyStr(a->Guid) == false) { char class_key[MAX_SIZE]; char short_key[MAX_SIZE]; if (GetClassRegKeyWin32(class_key, sizeof(class_key), short_key, sizeof(short_key), a->Guid)) { char *device_instance_id = MsRegReadStr(REG_LOCAL_MACHINE, class_key, "DeviceInstanceID"); if (IsEmptyStr(device_instance_id)) { Free(device_instance_id); device_instance_id = SearchDeviceInstanceIdFromShortKey(short_key); } if (IsEmptyStr(device_instance_id) == false) { char device_key[MAX_SIZE]; char *service_name; Format(device_key, sizeof(device_key), "SYSTEM\\CurrentControlSet\\Enum\\%s", device_instance_id); service_name = MsRegReadStr(REG_LOCAL_MACHINE, device_key, "Service"); if (IsEmptyStr(service_name) == false) { char service_key[MAX_SIZE]; char *sys; Format(service_key, sizeof(service_key), "SYSTEM\\CurrentControlSet\\services\\%s", service_name); sys = MsRegReadStr(REG_LOCAL_MACHINE, service_key, "ImagePath"); if (IsEmptyStr(sys) == false) { char sysname[MAX_PATH]; GetFileNameFromFilePath(sysname, sizeof(sysname), sys); Trim(sysname); if (EndWith(sysname, ".sys")) { // device found RPC_ENUM_ETH_VLAN_ITEM *e = ZeroMalloc(sizeof(RPC_ENUM_ETH_VLAN_ITEM)); StrCpy(e->DeviceName, sizeof(e->DeviceName), a->Title); StrCpy(e->Guid, sizeof(e->Guid), a->Guid); StrCpy(e->DeviceInstanceId, sizeof(e->DeviceInstanceId), device_instance_id); StrCpy(e->DriverName, sizeof(e->DriverName), sysname); // Get VLAN tag pass-through availability of the device GetVLanSupportStatus(e); // Get current pass-through setting of the device GetVLanEnableStatus(e); Insert(o, e); } } Free(sys); } Free(service_name); } Free(device_instance_id); } } } t->NumItem = LIST_NUM(o); t->Items = ZeroMalloc(sizeof(RPC_ENUM_ETH_VLAN_ITEM) * i); for (i = 0;i < LIST_NUM(o);i++) { RPC_ENUM_ETH_VLAN_ITEM *e = LIST_DATA(o, i); Copy(&t->Items[i], e, sizeof(RPC_ENUM_ETH_VLAN_ITEM)); Free(e); } ReleaseList(o); Unlock(eth_list_lock); return true; }
LIST *GetEthAdapterListInternal() { LIST *o; LIST *ret; UINT size; char *buf; UINT i, j; char *qos_tag = " (Microsoft's Packet Scheduler)"; SU *su = NULL; LIST *su_adapter_list = NULL; // Try to use SeLow if (enable_selow) { su = SuInit(); } o = NewListFast(CompareWpAdapter); size = 200000; buf = ZeroMalloc(size); // Try to enumerate with SeLow if (su != NULL) { su_adapter_list = SuGetAdapterList(su); if (su_adapter_list == NULL) { // Fail to enumerate SuFree(su); su = NULL; //WHERE; is_using_selow = false; } else { //WHERE; is_using_selow = true; } } else { is_using_selow = false; } if (su_adapter_list != NULL) { // If 1 or more adapters are enumerated by SeLow, create adapter list object UINT i; for (i = 0;i < LIST_NUM(su_adapter_list);i++) { SU_ADAPTER_LIST *t = LIST_DATA(su_adapter_list, i); WP_ADAPTER *a = ZeroMalloc(sizeof(WP_ADAPTER)); StrCpy(a->Name, sizeof(a->Name), t->Name); StrCpy(a->Guid, sizeof(a->Guid), t->Guid); StrCpy(a->Title, sizeof(a->Title), t->Info.FriendlyName); TrimCrlf(a->Title); Trim(a->Title); TrimCrlf(a->Title); Trim(a->Title); if (EndWith(a->Title, qos_tag)) { a->Title[StrLen(a->Title) - StrLen(qos_tag)] = 0; TrimCrlf(a->Title); Trim(a->Title); TrimCrlf(a->Title); Trim(a->Title); } Add(o, a); } } else { // When SeLow is not used, create adapter list with SEE or WinPcap if (wp->PacketGetAdapterNames(buf, &size) == false) { Free(buf); return o; } i = 0; if (OS_IS_WINDOWS_NT(GetOsInfo()->OsType)) { // Windows NT if (size >= 2 && buf[0] != 0 && buf[1] != 0) { goto ANSI_STR; } while (true) { wchar_t tmp[MAX_SIZE]; WP_ADAPTER *a; UniStrCpy(tmp, sizeof(tmp), L""); if (*((wchar_t *)(&buf[i])) == 0) { i += sizeof(wchar_t); break; } for (;*((wchar_t *)(&buf[i])) != 0;i += sizeof(wchar_t)) { wchar_t str[2]; str[0] = *((wchar_t *)(&buf[i])); str[1] = 0; UniStrCat(tmp, sizeof(tmp), str); } i += sizeof(wchar_t); a = ZeroMalloc(sizeof(WP_ADAPTER)); UniToStr(a->Name, sizeof(a->Name), tmp); Add(o, a); } } else { // Windows 9x ANSI_STR: while (true) { char tmp[MAX_SIZE]; WP_ADAPTER *a; StrCpy(tmp, sizeof(tmp), ""); if (*((char *)(&buf[i])) == 0) { i += sizeof(char); break; } for (;*((char *)(&buf[i])) != 0;i += sizeof(char)) { char str[2]; str[0] = *((char *)(&buf[i])); str[1] = 0; StrCat(tmp, sizeof(tmp), str); } i += sizeof(char); a = ZeroMalloc(sizeof(WP_ADAPTER)); StrCpy(a->Name, sizeof(a->Name), tmp); Add(o, a); } } for (j = 0;j < LIST_NUM(o);j++) { WP_ADAPTER *a = LIST_DATA(o, j); StrCpy(a->Title, sizeof(a->Title), &buf[i]); i += StrSize(a->Title); // If device description is "Unknown" in Win9x, skip 1 byte if (OS_IS_WINDOWS_9X(GetOsInfo()->OsType)) { if (StrCmp(a->Title, "Unknown") == 0) { if (buf[i] == 0) { i+=sizeof(char); } } } TrimCrlf(a->Title); Trim(a->Title); TrimCrlf(a->Title); Trim(a->Title); if (EndWith(a->Title, qos_tag)) { a->Title[StrLen(a->Title) - StrLen(qos_tag)] = 0; TrimCrlf(a->Title); Trim(a->Title); TrimCrlf(a->Title); Trim(a->Title); } } } for (j = 0;j < LIST_NUM(o);j++) { // Extract GUID WP_ADAPTER *a = LIST_DATA(o, j); if (IsEmptyStr(a->Guid)) { StrCpy(a->Guid, sizeof(a->Guid), a->Name); ReplaceStr(a->Guid, sizeof(a->Guid), a->Guid, "\\Device\\SEE_", ""); ReplaceStr(a->Guid, sizeof(a->Guid), a->Guid, "\\Device\\NPF_", ""); ReplaceStr(a->Guid, sizeof(a->Guid), a->Guid, "\\Device\\PCD_", ""); } } // Sort if (su_adapter_list != NULL) { // Since adapter list made by SeLow is already sorted, don't sort here Sort(o); } ret = NewListFast(CompareWpAdapter); for (i = 0;i < LIST_NUM(o);i++) { WP_ADAPTER *a = LIST_DATA(o, i); ADAPTER *ad; bool is_ethernet = false; bool ok = false; if (SearchStrEx(a->Title, "ppp", 0, false) != INFINITE || SearchStrEx(a->Title, "wan", 0, false) != INFINITE || SearchStrEx(a->Title, "dialup", 0, false) != INFINITE || SearchStrEx(a->Title, "pptp", 0, false) != INFINITE || SearchStrEx(a->Title, "telepho", 0, false) != INFINITE || SearchStrEx(a->Title, "modem", 0, false) != INFINITE || SearchStrEx(a->Title, "ras", 0, false) != INFINITE) { Free(a); continue; } // Determine whether the adapter type is Ethernet if (su == NULL) { // Determine with See ad = wp->PacketOpenAdapter(a->Name); if (ad != NULL) { NetType type; if (wp->PacketGetNetType(ad, &type)) { if (type.LinkType == 0) { is_ethernet = true; } } wp->PacketCloseAdapter(ad); } } else { // In using SeLow, all devices should be Ethernet device is_ethernet = true; } if (is_ethernet) { // Add only Ethernet device char tmp[MAX_SIZE]; UINT k; StrCpy(tmp, sizeof(tmp), a->Title); for (k = 0;;k++) { if (k == 0) { StrCpy(tmp, sizeof(tmp), a->Title); } else { Format(tmp, sizeof(tmp), "%s (%u)", a->Title, k + 1); } ok = true; for (j = 0;j < LIST_NUM(ret);j++) { WP_ADAPTER *aa = LIST_DATA(ret, j); if (StrCmpi(aa->Title, tmp) == 0) { ok = false; } } if (ok) { break; } } StrCpy(a->Title, sizeof(a->Title), tmp); a->Id = Win32EthGenIdFromGuid(a->Guid); Add(ret, a); } if (ok == false) { Free(a); } } Free(buf); Sort(ret); ReleaseList(o); if (su != NULL) { SuFreeAdapterList(su_adapter_list); SuFree(su); } return ret; }
bool DispatchNextCmdEx(CONSOLE *c, wchar_t *exec_command, char *prompt, CMD cmd[], UINT num_cmd, void *param) { wchar_t *str; wchar_t *tmp; char *cmd_name; bool b_exit = false; wchar_t *cmd_param; UINT ret = ERR_NO_ERROR; TOKEN_LIST *t; TOKEN_LIST *candidate; bool no_end_crlf = false; UINT i; // Validate arguments if (c == NULL || (num_cmd >= 1 && cmd == NULL)) { return false; } if (exec_command == NULL) { // Show the prompt RETRY: tmp = CopyStrToUni(prompt); if (c->ProgrammingMode) { wchar_t tmp2[MAX_PATH]; UniFormat(tmp2, sizeof(tmp2), L"[PROMPT:%u:%s]\r\n", c->RetCode, tmp); Free(tmp); tmp = CopyUniStr(tmp2); } str = c->ReadLine(c, tmp, false); Free(tmp); if (str != NULL && IsEmptyUniStr(str)) { Free(str); goto RETRY; } } else { wchar_t tmp[MAX_SIZE]; // Use exec_command if (UniStartWith(exec_command, L"vpncmd") == false) { if (prompt != NULL) { if (c->ConsoleType != CONSOLE_CSV) { UniFormat(tmp, sizeof(tmp), L"%S%s", prompt, exec_command); c->Write(c, tmp); } } } str = CopyUniStr(exec_command); } if (str == NULL) { // User canceled return false; } UniTrimCrlf(str); UniTrim(str); if (UniIsEmptyStr(str)) { // Do Nothing Free(str); return true; } // Divide into command name and parameter if (SeparateCommandAndParam(str, &cmd_name, &cmd_param) == false) { // Do Nothing Free(str); return true; } if (StrLen(cmd_name) >= 2 && cmd_name[0] == '?' && cmd_name[1] != '?') { char tmp[MAX_SIZE]; wchar_t *s; StrCpy(tmp, sizeof(tmp), cmd_name + 1); StrCpy(cmd_name, 0, tmp); s = UniCopyStr(L"/?"); Free(cmd_param); cmd_param = s; } if (StrLen(cmd_name) >= 2 && EndWith(cmd_name, "?") && cmd_name[StrLen(cmd_name) - 2] != '?') { wchar_t *s; cmd_name[StrLen(cmd_name) - 1] = 0; s = UniCopyStr(L"/?"); Free(cmd_param); cmd_param = s; } // Get the candidate of command t = ZeroMalloc(sizeof(TOKEN_LIST)); t->NumTokens = num_cmd; t->Token = ZeroMalloc(sizeof(char *) * t->NumTokens); for (i = 0;i < t->NumTokens;i++) { t->Token[i] = CopyStr(cmd[i].Name); } if (IsHelpStr(cmd_name)) { if (UniIsEmptyStr(cmd_param)) { wchar_t tmp[MAX_SIZE]; // Display the list of commands that can be used UniFormat(tmp, sizeof(tmp), _UU("CMD_HELP_1"), t->NumTokens); c->Write(c, tmp); PrintCandidateHelp(c, NULL, t, 1); c->Write(c, L""); c->Write(c, _UU("CMD_HELP_2")); } else { char *cmd_name; // Display the help for the specified command if (SeparateCommandAndParam(cmd_param, &cmd_name, NULL)) { bool b = true; if (IsHelpStr(cmd_name)) { b = false; } if (b) { wchar_t str[MAX_SIZE]; UniFormat(str, sizeof(str), L"%S /help", cmd_name); DispatchNextCmdEx(c, str, NULL, cmd, num_cmd, param); no_end_crlf = true; } Free(cmd_name); } } } else if (StrCmpi(cmd_name, "exit") == 0 || StrCmpi(cmd_name, "quit") == 0) { // Exit b_exit = true; } else { candidate = GetRealnameCandidate(cmd_name, t); if (candidate == NULL || candidate->NumTokens == 0) { wchar_t tmp[MAX_SIZE]; // No candidate UniFormat(tmp, sizeof(tmp), _UU("CON_UNKNOWN_CMD"), cmd_name); c->Write(c, tmp); c->RetCode = ERR_BAD_COMMAND_OR_PARAM; } else if (candidate->NumTokens >= 2) { wchar_t tmp[MAX_SIZE]; // There is more than one candidate UniFormat(tmp, sizeof(tmp), _UU("CON_AMBIGIOUS_CMD"), cmd_name); c->Write(c, tmp); c->Write(c, _UU("CON_AMBIGIOUS_CMD_1")); PrintCandidateHelp(c, NULL, candidate, 1); c->Write(c, _UU("CON_AMBIGIOUS_CMD_2")); c->RetCode = ERR_BAD_COMMAND_OR_PARAM; } else { char *real_cmd_name; UINT i; // The candidate was shortlisted to one real_cmd_name = candidate->Token[0]; for (i = 0;i < num_cmd;i++) { if (StrCmpi(cmd[i].Name, real_cmd_name) == 0) { if (cmd[i].Proc != NULL) { // Show the description of the command if it isn't in CSV mode if(c->ConsoleType != CONSOLE_CSV) { wchar_t tmp[256]; wchar_t *note; GetCommandHelpStr(cmd[i].Name, ¬e, NULL, NULL); UniFormat(tmp, sizeof(tmp), _UU("CMD_EXEC_MSG_NAME"), cmd[i].Name, note); c->Write(c, tmp); } // Call the procedure of the command ret = cmd[i].Proc(c, cmd[i].Name, cmd_param, param); if (ret == INFINITE) { // Exit command b_exit = true; } else { c->RetCode = ret; } } } } } FreeToken(candidate); } FreeToken(t); Free(str); Free(cmd_name); Free(cmd_param); if (no_end_crlf == false) { //c->Write(c, L""); } if (b_exit) { return false; } return true; }
// main function int main(int argc, char *argv[]) { wchar_t *s; UINT ret = 0; InitProcessCallOnce(); #ifdef OS_WIN32 SetConsoleTitleA(CEDAR_PRODUCT_STR " VPN Command Line Utility"); #else // For *nix, disable output buffering to allow for interactive use setbuf(stdout,NULL); #endif // OS_WIN32 #if defined(_DEBUG) || defined(DEBUG) // In VC++ compilers, the macro is "_DEBUG", not "DEBUG". // If set memcheck = true, the program will be vitally slow since it will log all malloc() / realloc() / free() calls to find the cause of memory leak. // For normal debug we set memcheck = false. // Please set memcheck = true if you want to test the cause of memory leaks. InitMayaqua(false, true, argc, argv); #else InitMayaqua(false, false, argc, argv); #endif InitCedar(); s = GetCommandLineUniStr(); if (s == NULL) { s = CopyUniStr(L""); } if (UniStrCmpi(s, L"exit") != 0) { UINT size = UniStrSize(s) + 64; wchar_t *tmp; tmp = Malloc(size); UniFormat(tmp, size, L"vpncmd %s", s); ret = CommandMain(tmp); Free(tmp); } #ifdef OS_WIN32 { UINT i; LIST *o = MsGetProcessList(); bool b = false; for (i = 0;i < LIST_NUM(o);i++) { MS_PROCESS *p = LIST_DATA(o, i); if (EndWith(p->ExeFilename, "\\cmd.exe") || EndWith(p->ExeFilename, "\\command.com")) { b = true; break; } } MsFreeProcessList(o); if (b == false) { if (ret != ERR_NO_ERROR) { SleepThread(1000); } } } #endif // OS_WIN32 Free(s); FreeCedar(); FreeMayaqua(); return ret; }
// Read a string table from the buffer bool LoadTableFromBuf(BUF *b) { char *tmp; char prefix[MAX_SIZE]; LIST *replace_list = NULL; UINT i; // Validate arguments if (b == NULL) { return false; } // If the table already exists, delete it FreeTable(); // Create a list TableList = NewList(CmpTableName); Zero(prefix, sizeof(prefix)); replace_list = NewListFast(NULL); // Read the contents of the buffer line by line while (true) { TABLE *t; bool ok = true; tmp = CfgReadNextLine(b); if (tmp == NULL) { break; } if (tmp[0] == '$') { char key[128]; char value[MAX_SIZE]; if (GetKeyAndValue(tmp, key, sizeof(key), value, sizeof(value), " \t")) { if (StartWith(key, "$") && EndWith(key, "$") && StrLen(key) >= 3) { TABLE *t; wchar_t univalue[MAX_SIZE]; wchar_t uniname[MAX_SIZE]; t = ZeroMalloc(sizeof(TABLE)); Zero(univalue, sizeof(univalue)); Utf8ToUni(univalue, sizeof(univalue), value, StrLen(value)); StrToUni(uniname, sizeof(uniname), key); t->name = (char *)CopyUniStr(uniname); t->unistr = CopyUniStr(univalue); Add(replace_list, t); // Found a replacement definition ok = false; } } } if (ok) { t = ParseTableLine(tmp, prefix, sizeof(prefix), replace_list); if (t != NULL) { // Register Insert(TableList, t); } } Free(tmp); } for (i = 0;i < LIST_NUM(replace_list);i++) { TABLE *t = LIST_DATA(replace_list, i); Free(t->name); Free(t->str); Free(t->unistr); Free(t); } ReleaseList(replace_list); return true; }