Clean up the Icinga plugins a bit

This commit is contained in:
Gunnar Beutner 2018-02-01 08:45:09 +01:00
parent e952302e08
commit 0c006637ea
28 changed files with 1225 additions and 1611 deletions

View File

@ -40,7 +40,7 @@ if (WIN32)
add_definitions(-DUNICODE -D_UNICODE) add_definitions(-DUNICODE -D_UNICODE)
set(thresholds_SOURCES set(thresholds_SOURCES
thresholds.cpp thresholds.h thresholds.cpp thresholds.hpp
) )
add_library(thresholds ${thresholds_SOURCES}) add_library(thresholds ${thresholds_SOURCES})
@ -59,10 +59,9 @@ if (WIN32)
foreach(source ${check_SOURCES}) foreach(source ${check_SOURCES})
string(REGEX REPLACE ".cpp\$" "" check_OUT "${source}") string(REGEX REPLACE ".cpp\$" "" check_OUT "${source}")
string(REGEX REPLACE ".cpp\$" ".h" check_HEADER "${source}")
add_executable(${check_OUT} ${source} ${check_HEADER}) add_executable(${check_OUT} ${source})
target_link_libraries(${check_OUT} thresholds Shlwapi.lib ${Boost_PROGRAM_OPTIONS_LIBRARY}) target_link_libraries(${check_OUT} thresholds shlwapi.lib ${Boost_PROGRAM_OPTIONS_LIBRARY})
set_target_properties( set_target_properties(
${check_OUT} PROPERTIES ${check_OUT} PROPERTIES
@ -72,11 +71,11 @@ if (WIN32)
) )
endforeach() endforeach()
target_link_libraries(check_load Pdh.lib) target_link_libraries(check_load pdh.lib)
target_link_libraries(check_network Pdh.lib Iphlpapi.lib) target_link_libraries(check_network pdh.lib iphlpapi.lib)
target_link_libraries(check_perfmon Pdh.lib) target_link_libraries(check_perfmon pdh.lib)
target_link_libraries(check_ping Ntdll.lib iphlpapi.lib Ws2_32.lib) target_link_libraries(check_ping ntdll.lib iphlpapi.lib ws2_32.lib)
target_link_libraries(check_procs Pdh.lib) target_link_libraries(check_procs pdh.lib)
target_link_libraries(check_uptime ${Boost_SYSTEM_LIBRARY}) target_link_libraries(check_uptime ${Boost_SYSTEM_LIBRARY})
target_link_libraries(check_users wtsapi32.lib) target_link_libraries(check_users wtsapi32.lib)

View File

@ -16,13 +16,16 @@
* along with this program; if not, write to the Free Software Foundation * * along with this program; if not, write to the Free Software Foundation *
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA. * * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA. *
******************************************************************************/ ******************************************************************************/
#include <set>
#include <Shlwapi.h>
#include <iostream>
#include <math.h>
#include <functional>
#include "check_disk.h" #include "plugins/thresholds.hpp"
#include <boost/program_options.hpp>
#include <vector>
#include <windows.h>
#include <set>
#include <iostream>
#include <functional>
#include <shlwapi.h>
#include <math.h>
using namespace std::placeholders; using namespace std::placeholders;
@ -30,42 +33,189 @@ using namespace std::placeholders;
namespace po = boost::program_options; namespace po = boost::program_options;
static BOOL debug = FALSE; struct drive
INT wmain(INT argc, WCHAR **argv)
{ {
std::vector<drive> vDrives; std::wstring name;
printInfoStruct printInfo{ }; double cap;
po::variables_map vm; double free;
double used;
INT ret; drive(std::wstring p)
: name(p)
{ }
};
ret = parseArguments(argc, argv, vm, printInfo); struct printInfoStruct
if (ret != -1) {
return ret; threshold warn;
threshold crit;
std::vector<std::wstring> drives;
std::vector<std::wstring> exclude_drives;
Bunit unit;
bool showUsed{false};
};
printInfo.warn.legal = !printInfo.warn.legal; static bool l_Debug;
printInfo.crit.legal = !printInfo.crit.legal;
if (printInfo.drives.empty()) static int check_drives(std::vector<drive>& vDrives, std::vector<std::wstring>& vExclude_Drives)
ret = check_drives(vDrives, printInfo.exclude_drives); {
else DWORD dwResult, dwSize = 0, dwVolumePathNamesLen = MAX_PATH + 1;
ret = check_drives(vDrives, printInfo); WCHAR szLogicalDrives[1024], szVolumeName[MAX_PATH], *szVolumePathNames = NULL;
HANDLE hVolume = NULL;
std::wstring wsLogicalDrives;
size_t volumeNameEnd = 0;
if (ret != -1) std::set<std::wstring> sDrives;
return ret;
for (std::vector<drive>::iterator it = vDrives.begin(); it != vDrives.end(); ++it) { if (l_Debug)
if (!getDriveSpaceValues(*it, printInfo.unit)) { std::wcout << "Getting logic drive string (includes network drives)\n";
std::wcout << "Failed to access drive at " << it->name << '\n';
return 3; dwResult = GetLogicalDriveStrings(MAX_PATH, szLogicalDrives);
if (dwResult > MAX_PATH)
goto die;
if (l_Debug)
std::wcout << "Splitting string into single drive names\n";
LPTSTR szSingleDrive = szLogicalDrives;
while (*szSingleDrive) {
std::wstring drname = szSingleDrive;
sDrives.insert(drname);
szSingleDrive += wcslen(szSingleDrive) + 1;
if (l_Debug)
std::wcout << "Got: " << drname << '\n';
}
if (l_Debug)
std::wcout << "Getting volume mountpoints (includes NTFS folders)\n"
<< "Getting first volume\n";
hVolume = FindFirstVolume(szVolumeName, MAX_PATH);
if (hVolume == INVALID_HANDLE_VALUE)
goto die;
if (l_Debug)
std::wcout << "Traversing through list of drives\n";
while (GetLastError() != ERROR_NO_MORE_FILES) {
if (l_Debug)
std::wcout << "Path name for " << szVolumeName << "= \"";
volumeNameEnd = wcslen(szVolumeName) - 1;
szVolumePathNames = new WCHAR[dwVolumePathNamesLen];
while (!GetVolumePathNamesForVolumeName(szVolumeName, szVolumePathNames, dwVolumePathNamesLen,
&dwVolumePathNamesLen)) {
if (GetLastError() != ERROR_MORE_DATA)
break;
delete[] szVolumePathNames;
szVolumePathNames = new WCHAR[dwVolumePathNamesLen];
}
if (l_Debug)
std::wcout << szVolumePathNames << "\"\n";
sDrives.insert(std::wstring(szVolumePathNames));
FindNextVolume(hVolume, szVolumeName, MAX_PATH);
}
if (l_Debug)
std::wcout << "Creating vector from found volumes, ignoring CD drives etc.:\n";
for (const auto& driveName : sDrives) {
unsigned int type = GetDriveType(driveName.c_str());
if (type == DRIVE_FIXED || type == DRIVE_REMOTE) {
if (l_Debug)
std::wcout << "\t" << driveName << '\n';
vDrives.push_back(drive(driveName));
} }
} }
return printOutput(printInfo, vDrives); FindVolumeClose(hVolume);
if (szVolumePathNames)
delete[] szVolumePathNames;
if (l_Debug)
std::wcout << "Removing excluded drives\n";
for (const auto& driveName : vExclude_Drives) {
vDrives.erase(std::remove_if(vDrives.begin(), vDrives.end(),
[&driveName](const drive& d) { return d.name == driveName + L'\\'; }),
vDrives.end());
}
return -1;
die:
if (hVolume)
FindVolumeClose(hVolume);
printErrorInfo();
return 3;
} }
static INT parseArguments(INT ac, WCHAR **av, po::variables_map& vm, printInfoStruct& printInfo) static int check_drives(std::vector<drive>& vDrives, printInfoStruct& printInfo)
{
if (l_Debug)
std::wcout << "Removing excluded drives from user input drives\n";
for (const auto& driveName : printInfo.exclude_drives) {
printInfo.drives.erase(std::remove(printInfo.drives.begin(), printInfo.drives.end(), driveName),
printInfo.drives.end());
}
if (l_Debug)
std::wcout << "Parsing user input drive names\n";
for (auto& driveName : printInfo.drives) {
if (driveName.at(driveName.length() - 1) != *L"\\")
driveName.append(L"\\");
if (std::wstring::npos == driveName.find(L":\\")) {
std::wcout << "A \":\" is required after the drive name of " << driveName << '\n';
return 3;
}
if (l_Debug)
std::wcout << "Added " << driveName << '\n';
vDrives.emplace_back(driveName);
}
return -1;
}
static bool getDriveSpaceValues(drive& drive, const Bunit& unit)
{
if (l_Debug)
std::wcout << "Getting free and used disk space for drive " << drive.name << '\n';
ULARGE_INTEGER tempFree, tempTotal;
if (!GetDiskFreeSpaceEx(drive.name.c_str(), NULL, &tempTotal, &tempFree))
return false;
ULARGE_INTEGER tempUsed;
tempUsed.QuadPart = tempTotal.QuadPart - tempFree.QuadPart;
if (l_Debug)
std::wcout << "\tcap: " << tempFree.QuadPart << '\n';
drive.cap = round((tempTotal.QuadPart / pow(1024.0, unit)));
if (l_Debug)
std::wcout << "\tAfter conversion: " << drive.cap << '\n'
<< "\tfree: " << tempFree.QuadPart << '\n';
drive.free = round((tempFree.QuadPart / pow(1024.0, unit)));
if (l_Debug)
std::wcout << "\tAfter conversion: " << drive.free << '\n'
<< "\tused: " << tempUsed.QuadPart << '\n';
drive.used = round((tempUsed.QuadPart / pow(1024.0, unit)));
if (l_Debug)
std::wcout << "\tAfter conversion: " << drive.used << '\n' << '\n';
return true;
}
static int parseArguments(int ac, WCHAR **av, po::variables_map& vm, printInfoStruct& printInfo)
{ {
WCHAR namePath[MAX_PATH]; WCHAR namePath[MAX_PATH];
GetModuleFileName(NULL, namePath, MAX_PATH); GetModuleFileName(NULL, namePath, MAX_PATH);
@ -89,19 +239,19 @@ static INT parseArguments(INT ac, WCHAR **av, po::variables_map& vm, printInfoSt
("megabytes,m", "use megabytes, overridden by -unit") ("megabytes,m", "use megabytes, overridden by -unit")
; ;
po::basic_command_line_parser<WCHAR> parser(ac, av); po::wcommand_line_parser parser(ac, av);
try { try {
po::store( po::store(
parser parser
.options(desc) .options(desc)
.style( .style(
po::command_line_style::unix_style | po::command_line_style::unix_style |
po::command_line_style::allow_long_disguise) po::command_line_style::allow_long_disguise)
.run(), .run(),
vm); vm);
vm.notify(); vm.notify();
} catch (std::exception& e) { } catch (const std::exception& e) {
std::cout << e.what() << '\n' << desc << '\n'; std::cout << e.what() << '\n' << desc << '\n';
return 3; return 3;
} }
@ -152,7 +302,7 @@ static INT parseArguments(INT ac, WCHAR **av, po::variables_map& vm, printInfoSt
if (vm.count("warning")) { if (vm.count("warning")) {
try { try {
printInfo.warn = threshold(vm["warning"].as<std::wstring>()); printInfo.warn = threshold(vm["warning"].as<std::wstring>());
} catch (std::invalid_argument& e) { } catch (const std::invalid_argument& e) {
std::cout << e.what() << '\n'; std::cout << e.what() << '\n';
return 3; return 3;
} }
@ -160,7 +310,7 @@ static INT parseArguments(INT ac, WCHAR **av, po::variables_map& vm, printInfoSt
if (vm.count("critical")) { if (vm.count("critical")) {
try { try {
printInfo.crit = threshold(vm["critical"].as<std::wstring>()); printInfo.crit = threshold(vm["critical"].as<std::wstring>());
} catch (std::invalid_argument& e) { } catch (const std::invalid_argument& e) {
std::cout << e.what() << '\n'; std::cout << e.what() << '\n';
return 3; return 3;
} }
@ -175,7 +325,7 @@ static INT parseArguments(INT ac, WCHAR **av, po::variables_map& vm, printInfoSt
if (vm.count("unit")) { if (vm.count("unit")) {
try { try {
printInfo.unit = parseBUnit(vm["unit"].as<std::wstring>()); printInfo.unit = parseBUnit(vm["unit"].as<std::wstring>());
} catch (std::invalid_argument) { } catch (const std::invalid_argument&) {
std::wcout << "Unknown unit Type " << vm["unit"].as<std::wstring>() << '\n'; std::wcout << "Unknown unit Type " << vm["unit"].as<std::wstring>() << '\n';
return 3; return 3;
} }
@ -188,15 +338,14 @@ static INT parseArguments(INT ac, WCHAR **av, po::variables_map& vm, printInfoSt
printInfo.showUsed = vm.count("show-used") > 0; printInfo.showUsed = vm.count("show-used") > 0;
if (vm.count("debug")) l_Debug = vm.count("debug") > 0;
debug = TRUE;
return -1; return -1;
} }
static INT printOutput(printInfoStruct& printInfo, std::vector<drive>& vDrives) static int printOutput(printInfoStruct& printInfo, std::vector<drive>& vDrives)
{ {
if (debug) if (l_Debug)
std::wcout << "Constructing output string\n"; std::wcout << "Constructing output string\n";
std::vector<std::wstring> wsDrives, wsPerf; std::vector<std::wstring> wsDrives, wsPerf;
@ -216,8 +365,7 @@ static INT printOutput(printInfoStruct& printInfo, std::vector<drive>& vDrives)
tFree += it->free; tFree += it->free;
tUsed += it->used; tUsed += it->used;
if (printInfo.showUsed) if (printInfo.showUsed) {
{
wsDrives.push_back(it->name + L" " + removeZero(it->used) + L" " + unit + L" (" + wsDrives.push_back(it->name + L" " + removeZero(it->used) + L" " + unit + L" (" +
removeZero(std::round(it->used / it->cap * 100.0)) + L"%); "); removeZero(std::round(it->used / it->cap * 100.0)) + L"%); ");
@ -230,8 +378,7 @@ static INT printOutput(printInfoStruct& printInfo, std::vector<drive>& vDrives)
if (state == OK && printInfo.warn.set && !printInfo.warn.rend(it->used, it->cap)) if (state == OK && printInfo.warn.set && !printInfo.warn.rend(it->used, it->cap))
state = WARNING; state = WARNING;
} } else {
else {
wsDrives.push_back(it->name + L" " + removeZero(it->free) + L" " + unit + L" (" + wsDrives.push_back(it->name + L" " + removeZero(it->free) + L" " + unit + L" (" +
removeZero(std::round(it->free / it->cap * 100.0)) + L"%); "); removeZero(std::round(it->free / it->cap * 100.0)) + L"%); ");
@ -239,7 +386,7 @@ static INT printOutput(printInfoStruct& printInfo, std::vector<drive>& vDrives)
printInfo.warn.pString(it->cap) + L";" + printInfo.crit.pString(it->cap) + L";0;" printInfo.warn.pString(it->cap) + L";" + printInfo.crit.pString(it->cap) + L";0;"
+ removeZero(it->cap)); + removeZero(it->cap));
if ( printInfo.crit.rend(it->free, it->cap)) if (printInfo.crit.rend(it->free, it->cap))
state = CRITICAL; state = CRITICAL;
if (state == OK && printInfo.warn.rend(it->free, it->cap)) if (state == OK && printInfo.warn.rend(it->free, it->cap))
@ -263,186 +410,53 @@ static INT printOutput(printInfoStruct& printInfo, std::vector<drive>& vDrives)
std::wcout << output; std::wcout << output;
if (vDrives.size() > 1) { if (vDrives.size() > 1 && printInfo.showUsed) {
if (printInfo.showUsed) { std::wcout << "Total " << (printInfo.showUsed ? tUsed : tFree) << unit
std::wcout << "Total " << (printInfo.showUsed ? tUsed : tFree) << unit << " (" << removeZero(std::round(tUsed / tCap * 100.0)) << "%); ";
<< " (" << removeZero(std::round(tUsed / tCap * 100.0)) << "%); ";
}
} }
for (std::vector<std::wstring>::const_iterator it = wsDrives.begin(); it != wsDrives.end(); it++) for (const auto& driveName : wsDrives)
std::wcout << *it; std::wcout << driveName;
std::wcout << "|"; std::wcout << "|";
for (std::vector<std::wstring>::const_iterator it = wsPerf.begin(); it != wsPerf.end(); it++) for (const auto& perf : wsPerf)
std::wcout << *it; std::wcout << perf;
std::wcout << '\n'; std::wcout << '\n';
return state; return state;
} }
static INT check_drives(std::vector<drive>& vDrives, std::vector<std::wstring>& vExclude_Drives) int wmain(int argc, WCHAR **argv)
{ {
DWORD dwResult, dwSize = 0, dwVolumePathNamesLen = MAX_PATH + 1; std::vector<drive> vDrives;
WCHAR szLogicalDrives[1024], szVolumeName[MAX_PATH], *szVolumePathNames = NULL; printInfoStruct printInfo;
HANDLE hVolume = NULL; po::variables_map vm;
std::wstring wsLogicalDrives;
size_t volumeNameEnd = 0;
std::set<std::wstring> sDrives; int ret;
if (debug) ret = parseArguments(argc, argv, vm, printInfo);
std::wcout << "Getting logic drive string (includes network drives)\n"; if (ret != -1)
return ret;
dwResult = GetLogicalDriveStrings(MAX_PATH, szLogicalDrives); printInfo.warn.legal = !printInfo.warn.legal;
if (dwResult > MAX_PATH) printInfo.crit.legal = !printInfo.crit.legal;
goto die;
if (debug)
std::wcout << "Splitting string intoo single drive names\n";
LPTSTR szSingleDrive = szLogicalDrives; if (printInfo.drives.empty())
while (*szSingleDrive) { ret = check_drives(vDrives, printInfo.exclude_drives);
std::wstring drname = szSingleDrive; else
sDrives.insert(drname); ret = check_drives(vDrives, printInfo);
szSingleDrive += wcslen(szSingleDrive) + 1;
if (debug)
std::wcout << "Got: " << drname << '\n';
}
if (debug) if (ret != -1)
std::wcout << "Getting volume mountpoints (includes NTFS folders)\n" return ret;
<< "Getting first volume\n";
hVolume = FindFirstVolume(szVolumeName, MAX_PATH); for (std::vector<drive>::iterator it = vDrives.begin(); it != vDrives.end(); ++it) {
if (hVolume == INVALID_HANDLE_VALUE) if (!getDriveSpaceValues(*it, printInfo.unit)) {
goto die; std::wcout << "Failed to access drive at " << it->name << '\n';
if (debug)
std::wcout << "Traversing through list of drives\n";
while (GetLastError() != ERROR_NO_MORE_FILES) {
if (debug)
std::wcout << "Path name for " << szVolumeName << "= \"";
volumeNameEnd = wcslen(szVolumeName) - 1;
szVolumePathNames = reinterpret_cast<WCHAR*>(new WCHAR[dwVolumePathNamesLen]);
while (!GetVolumePathNamesForVolumeName(szVolumeName, szVolumePathNames, dwVolumePathNamesLen,
&dwVolumePathNamesLen)) {
if (GetLastError() != ERROR_MORE_DATA)
break;
delete[] reinterpret_cast<WCHAR*>(szVolumePathNames);
szVolumePathNames = reinterpret_cast<WCHAR*>(new WCHAR[dwVolumePathNamesLen]);
}
if (debug)
std::wcout << szVolumePathNames << "\"\n";
sDrives.insert(std::wstring(szVolumePathNames));
FindNextVolume(hVolume, szVolumeName, MAX_PATH);
}
if (debug)
std::wcout << "Creating vector from found volumes, ignoring cd drives etc.:\n";
for (std::set<std::wstring>::iterator it = sDrives.begin(); it != sDrives.end(); ++it) {
UINT type = GetDriveType(it->c_str());
if (type == DRIVE_FIXED || type == DRIVE_REMOTE) {
if (debug)
std::wcout << "\t" << *it << '\n';
vDrives.push_back(drive(*it));
}
}
FindVolumeClose(hVolume);
if (szVolumePathNames)
delete[] reinterpret_cast<WCHAR*>(szVolumePathNames);
if (!vExclude_Drives.empty()) {
if (debug)
std::wcout << "Removing excluded drives\n";
for (const std::wstring& wsDriveName : vExclude_Drives)
{
vDrives.erase(std::remove_if(vDrives.begin(), vDrives.end(),
std::bind(checkName, _1, wsDriveName + L'\\')), vDrives.end());
}
}
return -1;
die:
if (hVolume)
FindVolumeClose(hVolume);
die();
return 3;
}
static INT check_drives(std::vector<drive>& vDrives, printInfoStruct& printInfo)
{
if (!printInfo.exclude_drives.empty()) {
if (debug)
std::wcout << "Removing excluded drives from user input drives\n";
for (std::wstring& wsDrive : printInfo.exclude_drives)
{
printInfo.drives.erase(std::remove(printInfo.drives.begin(), printInfo.drives.end(), wsDrive),
printInfo.drives.end());
}
}
if (debug)
std::wcout << "Parsing user input drive names\n";
for (std::vector<std::wstring>::iterator it = printInfo.drives.begin();
it != printInfo.drives.end(); ++it) {
if (it->at(it->length() - 1) != *L"\\")
it->append(L"\\");
if (std::wstring::npos == it->find(L":\\")) {
std::wcout << "A \":\" is required after the drive name of " << *it << '\n';
return 3; return 3;
} }
if (debug)
std::wcout << "Added " << *it << '\n';
vDrives.push_back(drive(*it));
}
return -1;
}
static BOOL getDriveSpaceValues(drive& drive, const Bunit& unit)
{
if (debug)
std::wcout << "Getting free and used disk space for drive " << drive.name << '\n';
ULARGE_INTEGER tempFree, tempTotal, tempUsed;
if (!GetDiskFreeSpaceEx(drive.name.c_str(), NULL, &tempTotal, &tempFree)) {
return FALSE;
} }
tempUsed.QuadPart = tempTotal.QuadPart - tempFree.QuadPart; return printOutput(printInfo, vDrives);
if (debug)
std::wcout << "\tcap: " << tempFree.QuadPart << '\n';
drive.cap = round((tempTotal.QuadPart / pow(1024.0, unit)));
if (debug)
std::wcout << "\tAfter conversion: " << drive.cap << '\n'
<< "\tfree: " << tempFree.QuadPart << '\n';
drive.free = round((tempFree.QuadPart / pow(1024.0, unit)));
if (debug)
std::wcout << "\tAfter conversion: " << drive.free << '\n'
<< "\tused: " << tempUsed.QuadPart << '\n';
drive.used = round((tempUsed.QuadPart / pow(1024.0, unit)));
if (debug)
std::wcout << "\tAfter conversion: " << drive.used << '\n' << '\n';
return TRUE;
} }
static bool checkName(const drive& d, const std::wstring& s)
{
return (s == d.name);
}

View File

@ -17,40 +17,30 @@
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA. * * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA. *
******************************************************************************/ ******************************************************************************/
#include <Pdh.h> #include "plugins/thresholds.hpp"
#include <Shlwapi.h> #include <boost/program_options.hpp>
#include <pdhmsg.h> #include <boost/algorithm/string/split.hpp>
#include <boost/algorithm/string/classification.hpp>
#include <iostream> #include <iostream>
#include <pdh.h>
#include "check_load.h" #include <shlwapi.h>
#include <pdhmsg.h>
#include "boost/algorithm/string/split.hpp"
#include "boost/algorithm/string/classification.hpp"
#define VERSION 1.0 #define VERSION 1.0
namespace po = boost::program_options; namespace po = boost::program_options;
static BOOL debug = FALSE; struct printInfoStruct
INT wmain(INT argc, WCHAR **argv)
{ {
printInfoStruct printInfo{ }; threshold warn;
po::variables_map vm; threshold crit;
double load;
};
INT ret = parseArguments(argc, argv, vm, printInfo); static bool l_Debug;
if (ret != -1)
return ret;
ret = check_load(printInfo); static int parseArguments(int ac, WCHAR **av, po::variables_map& vm, printInfoStruct& printInfo)
if (ret != -1) {
return ret;
return printOutput(printInfo);
}
INT parseArguments(INT ac, WCHAR **av, po::variables_map& vm, printInfoStruct& printInfo) {
wchar_t namePath[MAX_PATH]; wchar_t namePath[MAX_PATH];
GetModuleFileName(NULL, namePath, MAX_PATH); GetModuleFileName(NULL, namePath, MAX_PATH);
wchar_t *progName = PathFindFileName(namePath); wchar_t *progName = PathFindFileName(namePath);
@ -65,19 +55,19 @@ INT parseArguments(INT ac, WCHAR **av, po::variables_map& vm, printInfoStruct& p
("critical,c", po::wvalue<std::wstring>(), "Critical value (in percent)") ("critical,c", po::wvalue<std::wstring>(), "Critical value (in percent)")
; ;
po::basic_command_line_parser<wchar_t> parser(ac, av); po::wcommand_line_parser parser(ac, av);
try { try {
po::store( po::store(
parser parser
.options(desc) .options(desc)
.style( .style(
po::command_line_style::unix_style | po::command_line_style::unix_style |
po::command_line_style::allow_long_disguise) po::command_line_style::allow_long_disguise)
.run(), .run(),
vm); vm);
vm.notify(); vm.notify();
} catch (std::exception& e) { } catch (const std::exception& e) {
std::cout << e.what() << '\n' << desc << '\n'; std::cout << e.what() << '\n' << desc << '\n';
return 3; return 3;
} }
@ -131,32 +121,32 @@ INT parseArguments(INT ac, WCHAR **av, po::variables_map& vm, printInfoStruct& p
std::vector<std::wstring> tokens; std::vector<std::wstring> tokens;
boost::algorithm::split(tokens, wthreshold, boost::algorithm::is_any_of(",")); boost::algorithm::split(tokens, wthreshold, boost::algorithm::is_any_of(","));
printInfo.warn = threshold(tokens[0]); printInfo.warn = threshold(tokens[0]);
} catch (std::invalid_argument& e) { } catch (const std::invalid_argument& e) {
std::cout << e.what() << '\n'; std::cout << e.what() << '\n';
return 3; return 3;
} }
} }
if (vm.count("critical")) { if (vm.count("critical")) {
try { try {
std::wstring cthreshold = vm["critical"].as<std::wstring>(); std::wstring cthreshold = vm["critical"].as<std::wstring>();
std::vector<std::wstring> tokens; std::vector<std::wstring> tokens;
boost::algorithm::split(tokens, cthreshold, boost::algorithm::is_any_of(",")); boost::algorithm::split(tokens, cthreshold, boost::algorithm::is_any_of(","));
printInfo.crit = threshold(tokens[0]); printInfo.crit = threshold(tokens[0]);
} catch (std::invalid_argument& e) { } catch (const std::invalid_argument& e) {
std::cout << e.what() << '\n'; std::cout << e.what() << '\n';
return 3; return 3;
} }
} }
if (vm.count("debug")) l_Debug = vm.count("debug") > 0;
debug = TRUE;
return -1; return -1;
} }
INT printOutput(printInfoStruct& printInfo) static int printOutput(printInfoStruct& printInfo)
{ {
if (debug) if (l_Debug)
std::wcout << L"Constructing output string" << '\n'; std::wcout << L"Constructing output string" << '\n';
state state = OK; state state = OK;
@ -167,82 +157,80 @@ INT printOutput(printInfoStruct& printInfo)
if (printInfo.crit.rend(printInfo.load)) if (printInfo.crit.rend(printInfo.load))
state = CRITICAL; state = CRITICAL;
std::wstringstream perf; std::wcout << L"LOAD ";
perf << L"% | load=" << printInfo.load << L"%;" << printInfo.warn.pString() << L";"
<< printInfo.crit.pString() << L";0;100" << '\n';
switch (state) { switch (state) {
case OK: case OK:
std::wcout << L"LOAD OK " << printInfo.load << perf.str(); std::wcout << L"OK";
break; break;
case WARNING: case WARNING:
std::wcout << L"LOAD WARNING " << printInfo.load << perf.str(); std::wcout << L"WARNING";
break; break;
case CRITICAL: case CRITICAL:
std::wcout << L"LOAD CRITICAL " << printInfo.load << perf.str(); std::wcout << L"CRITICAL";
break; break;
} }
std::wcout << " " << printInfo.load << L"% | load=" << printInfo.load << L"%;"
<< printInfo.warn.pString() << L";"
<< printInfo.crit.pString() << L";0;100" << '\n';
return state; return state;
} }
INT check_load(printInfoStruct& printInfo) static int check_load(printInfoStruct& printInfo)
{ {
PDH_HQUERY phQuery = NULL; if (l_Debug)
PDH_HCOUNTER phCounter;
DWORD dwBufferSize = 0;
DWORD CounterType;
PDH_FMT_COUNTERVALUE DisplayValue;
PDH_STATUS err;
LPCWSTR path = L"\\Processor(_Total)\\% Idle Time";
if (debug)
std::wcout << L"Creating query and adding counter" << '\n'; std::wcout << L"Creating query and adding counter" << '\n';
err = PdhOpenQuery(NULL, NULL, &phQuery); PDH_HQUERY phQuery;
PDH_STATUS err = PdhOpenQuery(NULL, NULL, &phQuery);
if (!SUCCEEDED(err)) if (!SUCCEEDED(err))
goto die; goto die;
err = PdhAddEnglishCounter(phQuery, path, NULL, &phCounter); PDH_HCOUNTER phCounter;
err = PdhAddEnglishCounter(phQuery, L"\\Processor(_Total)\\% Idle Time", NULL, &phCounter);
if (!SUCCEEDED(err)) if (!SUCCEEDED(err))
goto die; goto die;
if (debug) if (l_Debug)
std::wcout << L"Collecting first batch of query data" << '\n'; std::wcout << L"Collecting first batch of query data" << '\n';
err = PdhCollectQueryData(phQuery); err = PdhCollectQueryData(phQuery);
if (!SUCCEEDED(err)) if (!SUCCEEDED(err))
goto die; goto die;
if (debug) if (l_Debug)
std::wcout << L"Sleep for one second" << '\n'; std::wcout << L"Sleep for one second" << '\n';
Sleep(1000); Sleep(1000);
if (debug) if (l_Debug)
std::wcout << L"Collecting second batch of query data" << '\n'; std::wcout << L"Collecting second batch of query data" << '\n';
err = PdhCollectQueryData(phQuery); err = PdhCollectQueryData(phQuery);
if (!SUCCEEDED(err)) if (!SUCCEEDED(err))
goto die; goto die;
if (debug) if (l_Debug)
std::wcout << L"Creating formatted counter array" << '\n'; std::wcout << L"Creating formatted counter array" << '\n';
DWORD CounterType;
PDH_FMT_COUNTERVALUE DisplayValue;
err = PdhGetFormattedCounterValue(phCounter, PDH_FMT_DOUBLE, &CounterType, &DisplayValue); err = PdhGetFormattedCounterValue(phCounter, PDH_FMT_DOUBLE, &CounterType, &DisplayValue);
if (SUCCEEDED(err)) { if (SUCCEEDED(err)) {
if (DisplayValue.CStatus == PDH_CSTATUS_VALID_DATA) { if (DisplayValue.CStatus == PDH_CSTATUS_VALID_DATA) {
if (debug) if (l_Debug)
std::wcout << L"Recieved Value of " << DisplayValue.doubleValue << L" (idle)" << '\n'; std::wcout << L"Recieved Value of " << DisplayValue.doubleValue << L" (idle)" << '\n';
printInfo.load = 100.0 - DisplayValue.doubleValue; printInfo.load = 100.0 - DisplayValue.doubleValue;
} else { }
if (debug) else {
if (l_Debug)
std::wcout << L"Received data was not valid\n"; std::wcout << L"Received data was not valid\n";
goto die; goto die;
} }
if (debug) if (l_Debug)
std::wcout << L"Finished collection. Cleaning up and returning" << '\n'; std::wcout << L"Finished collection. Cleaning up and returning" << '\n';
PdhCloseQuery(phQuery); PdhCloseQuery(phQuery);
@ -250,8 +238,24 @@ INT check_load(printInfoStruct& printInfo)
} }
die: die:
die(); printErrorInfo();
if (phQuery) if (phQuery)
PdhCloseQuery(phQuery); PdhCloseQuery(phQuery);
return 3; return 3;
} }
int wmain(int argc, WCHAR **argv)
{
printInfoStruct printInfo;
po::variables_map vm;
int ret = parseArguments(argc, argv, vm, printInfo);
if (ret != -1)
return ret;
ret = check_load(printInfo);
if (ret != -1)
return ret;
return printOutput(printInfo);
}

View File

@ -1,35 +0,0 @@
/******************************************************************************
* Icinga 2 *
* Copyright (C) 2012-2018 Icinga Development Team (https://www.icinga.com/) *
* *
* This program is free software; you can redistribute it and/or *
* modify it under the terms of the GNU General Public License *
* as published by the Free Software Foundation; either version 2 *
* of the License, or (at your option) any later version. *
* *
* This program is distributed in the hope that it will be useful, *
* but WITHOUT ANY WARRANTY; without even the implied warranty of *
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
* GNU General Public License for more details. *
* *
* You should have received a copy of the GNU General Public License *
* along with this program; if not, write to the Free Software Foundation *
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA. *
******************************************************************************/
#ifndef CHECK_LOAD_H
#define CHECK_LOAD_H
#include "thresholds.h"
#include "boost/program_options.hpp"
struct printInfoStruct
{
threshold warn, crit;
DOUBLE load;
};
INT parseArguments(INT, WCHAR **, boost::program_options::variables_map&, printInfoStruct&);
INT printOutput(printInfoStruct&);
INT check_load(printInfoStruct&);
#endif // !CHECK_LOAD_H

View File

@ -1,50 +1,46 @@
/****************************************************************************** /******************************************************************************
* Icinga 2 * * Icinga 2 *
* Copyright (C) 2012-2018 Icinga Development Team (https://www.icinga.com/) * * Copyright (C) 2012-2018 Icinga Development Team (https://www.icinga.com/) *
* * * *
* This program is free software; you can redistribute it and/or * * This program is free software; you can redistribute it and/or *
* modify it under the terms of the GNU General Public License * * modify it under the terms of the GNU General Public License *
* as published by the Free Software Foundation; either version 2 * * as published by the Free Software Foundation; either version 2 *
* of the License, or (at your option) any later version. * * of the License, or (at your option) any later version. *
* * * *
* This program is distributed in the hope that it will be useful, * * This program is distributed in the hope that it will be useful, *
* but WITHOUT ANY WARRANTY; without even the implied warranty of * * but WITHOUT ANY WARRANTY; without even the implied warranty of *
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
* GNU General Public License for more details. * * GNU General Public License for more details. *
* * * *
* You should have received a copy of the GNU General Public License * * You should have received a copy of the GNU General Public License *
* along with this program; if not, write to the Free Software Foundation * * along with this program; if not, write to the Free Software Foundation *
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA. * * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA. *
******************************************************************************/ ******************************************************************************/
#include <Shlwapi.h>
#include <iostream>
#include <WinBase.h>
#include "check_memory.h" #include "plugins/thresholds.hpp"
#include <boost/program_options.hpp>
#include <iostream>
#include <shlwapi.h>
#include <winbase.h>
#define VERSION 1.0 #define VERSION 1.0
namespace po = boost::program_options; namespace po = boost::program_options;
static BOOL debug = FALSE; struct printInfoStruct
INT wmain(INT argc, WCHAR **argv)
{ {
printInfoStruct printInfo = {}; threshold warn;
po::variables_map vm; threshold crit;
double tRam;
double aRam;
double percentFree;
Bunit unit = BunitMB;
bool showUsed;
};
INT ret = parseArguments(argc, argv, vm, printInfo); static bool l_Debug;
if (ret != -1)
return ret;
ret = check_memory(printInfo); static int parseArguments(int ac, WCHAR ** av, po::variables_map& vm, printInfoStruct& printInfo)
if (ret != -1)
return ret;
return printOutput(printInfo);
}
INT parseArguments(INT ac, WCHAR ** av, po::variables_map& vm, printInfoStruct& printInfo)
{ {
WCHAR namePath[MAX_PATH]; WCHAR namePath[MAX_PATH];
GetModuleFileName(NULL, namePath, MAX_PATH); GetModuleFileName(NULL, namePath, MAX_PATH);
@ -62,19 +58,19 @@ INT parseArguments(INT ac, WCHAR ** av, po::variables_map& vm, printInfoStruct&
("show-used,U", "Show used memory instead of the free memory") ("show-used,U", "Show used memory instead of the free memory")
; ;
po::basic_command_line_parser<WCHAR> parser(ac, av); po::wcommand_line_parser parser(ac, av);
try { try {
po::store( po::store(
parser parser
.options(desc) .options(desc)
.style( .style(
po::command_line_style::unix_style | po::command_line_style::unix_style |
po::command_line_style::allow_long_disguise) po::command_line_style::allow_long_disguise)
.run(), .run(),
vm); vm);
vm.notify(); vm.notify();
} catch (std::exception& e) { } catch (const std::exception& e) {
std::cout << e.what() << '\n' << desc << '\n'; std::cout << e.what() << '\n' << desc << '\n';
return 3; return 3;
} }
@ -126,7 +122,7 @@ INT parseArguments(INT ac, WCHAR ** av, po::variables_map& vm, printInfoStruct&
if (vm.count("warning")) { if (vm.count("warning")) {
try { try {
printInfo.warn = threshold(vm["warning"].as<std::wstring>()); printInfo.warn = threshold(vm["warning"].as<std::wstring>());
} catch (std::invalid_argument& e) { } catch (const std::invalid_argument& e) {
std::cout << e.what() << '\n'; std::cout << e.what() << '\n';
return 3; return 3;
} }
@ -136,20 +132,19 @@ INT parseArguments(INT ac, WCHAR ** av, po::variables_map& vm, printInfoStruct&
if (vm.count("critical")) { if (vm.count("critical")) {
try { try {
printInfo.crit = threshold(vm["critical"].as<std::wstring>()); printInfo.crit = threshold(vm["critical"].as<std::wstring>());
} catch (std::invalid_argument& e) { } catch (const std::invalid_argument& e) {
std::cout << e.what() << '\n'; std::cout << e.what() << '\n';
return 3; return 3;
} }
printInfo.crit.legal = !printInfo.crit.legal; printInfo.crit.legal = !printInfo.crit.legal;
} }
if (vm.count("debug")) l_Debug = vm.count("debug") > 0;
debug = TRUE;
if (vm.count("unit")) { if (vm.count("unit")) {
try { try {
printInfo.unit = parseBUnit(vm["unit"].as<std::wstring>()); printInfo.unit = parseBUnit(vm["unit"].as<std::wstring>());
} catch (std::invalid_argument& e) { } catch (const std::invalid_argument& e) {
std::cout << e.what() << '\n'; std::cout << e.what() << '\n';
return 3; return 3;
} }
@ -160,69 +155,77 @@ INT parseArguments(INT ac, WCHAR ** av, po::variables_map& vm, printInfoStruct&
return -1; return -1;
} }
INT printOutput(printInfoStruct& printInfo) static int printOutput(printInfoStruct& printInfo)
{ {
if (debug) if (l_Debug)
std::wcout << L"Constructing output string" << '\n'; std::wcout << L"Constructing output string" << '\n';
state state; state state;
std::wstringstream output;
if (!printInfo.showUsed) { std::wcout << L"MEMORY ";
if (printInfo.warn.rend(printInfo.aRam, printInfo.tRam)) {
state = WARNING; double currentValue;
output << L"MEMORY WARNING - ";
} else if (printInfo.crit.rend(printInfo.aRam, printInfo.tRam)) { if (!printInfo.showUsed)
state = CRITICAL; currentValue = printInfo.aRam;
output << L"MEMORY CRITICAL - "; else
} else { currentValue = printInfo.tRam - printInfo.aRam;
state = OK;
output << L"MEMORY OK - "; if (printInfo.warn.rend(currentValue, printInfo.tRam)) {
} state = WARNING;
output << printInfo.percentFree << L"% free | memory = " << printInfo.aRam << BunitStr(printInfo.unit) << L";" std::wcout << L"WARNING";
<< printInfo.warn.pString(printInfo.tRam) << L";" << printInfo.crit.pString(printInfo.tRam) } else if (printInfo.crit.rend(currentValue, printInfo.tRam)) {
<< L";0;" << printInfo.tRam; state = CRITICAL;
std::wcout << L"CRITICAL";
} else { } else {
if (printInfo.warn.rend(printInfo.tRam - printInfo.aRam, printInfo.tRam)) { state = OK;
state = WARNING; std::wcout << L"OK";
output << L"MEMORY WARNING - ";
} else if (printInfo.crit.rend(printInfo.tRam - printInfo.aRam, printInfo.tRam)) {
state = CRITICAL;
output << L"MEMORY CRITICAL - ";
} else {
state = OK;
output << L"MEMORY OK - ";
}
output << 100 - printInfo.percentFree << L"% used | memory = " << printInfo.tRam - printInfo.aRam << BunitStr(printInfo.unit) << L";"
<< printInfo.warn.pString(printInfo.tRam) << L";" << printInfo.crit.pString(printInfo.tRam)
<< L";0;" << printInfo.tRam;
} }
std::wcout << output.str() << std::endl; if (!printInfo.showUsed)
std::wcout << " - " << printInfo.percentFree << L"% free";
else
std::wcout << " - " << 100 - printInfo.percentFree << L"% used";
std::wcout << "| memory=" << currentValue << BunitStr(printInfo.unit) << L";"
<< printInfo.warn.pString(printInfo.tRam) << L";" << printInfo.crit.pString(printInfo.tRam)
<< L";0;" << printInfo.tRam;
return state; return state;
} }
INT check_memory(printInfoStruct& printInfo) static int check_memory(printInfoStruct& printInfo)
{ {
if (debug) if (l_Debug)
std::wcout << L"Accessing memory statistics via MemoryStatus" << '\n'; std::wcout << L"Accessing memory statistics via MemoryStatus" << '\n';
_MEMORYSTATUSEX *pMemBuf = new _MEMORYSTATUSEX; MEMORYSTATUSEX memBuf;
memBuf.dwLength = sizeof(memBuf);
GlobalMemoryStatusEx(&memBuf);
pMemBuf->dwLength = sizeof(*pMemBuf); printInfo.tRam = round(memBuf.ullTotalPhys / pow(1024.0, printInfo.unit));
printInfo.aRam = round(memBuf.ullAvailPhys / pow(1024.0, printInfo.unit));
printInfo.percentFree = 100.0 * memBuf.ullAvailPhys / memBuf.ullTotalPhys;
GlobalMemoryStatusEx(pMemBuf); if (l_Debug)
std::wcout << L"Found memBuf.dwTotalPhys: " << memBuf.ullTotalPhys << '\n'
printInfo.tRam = round(pMemBuf->ullTotalPhys / pow(1024.0, printInfo.unit)); << L"Found memBuf.dwAvailPhys: " << memBuf.ullAvailPhys << '\n';
printInfo.aRam = round(pMemBuf->ullAvailPhys / pow(1024.0, printInfo.unit));
printInfo.percentFree = 100.0 * pMemBuf->ullAvailPhys / pMemBuf->ullTotalPhys;
if (debug)
std::wcout << L"Found pMemBuf->dwTotalPhys: " << pMemBuf->ullTotalPhys << '\n'
<< L"Found pMemBuf->dwAvailPhys: " << pMemBuf->ullAvailPhys << '\n';
delete pMemBuf;
return -1; return -1;
} }
int wmain(int argc, WCHAR **argv)
{
printInfoStruct printInfo = {};
po::variables_map vm;
int ret = parseArguments(argc, argv, vm, printInfo);
if (ret != -1)
return ret;
ret = check_memory(printInfo);
if (ret != -1)
return ret;
return printOutput(printInfo);
}

View File

@ -1,39 +0,0 @@
/******************************************************************************
* Icinga 2 *
* Copyright (C) 2012-2018 Icinga Development Team (https://www.icinga.com/) *
* *
* This program is free software; you can redistribute it and/or *
* modify it under the terms of the GNU General Public License *
* as published by the Free Software Foundation; either version 2 *
* of the License, or (at your option) any later version. *
* *
* This program is distributed in the hope that it will be useful, *
* but WITHOUT ANY WARRANTY; without even the implied warranty of *
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
* GNU General Public License for more details. *
* *
* You should have received a copy of the GNU General Public License *
* along with this program; if not, write to the Free Software Foundation *
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA. *
******************************************************************************/
#ifndef CHECK_MEMORY_H
#define CHECK_MEMORY_H
#include "thresholds.h"
#include "boost/program_options.hpp"
struct printInfoStruct
{
threshold warn, crit;
DOUBLE tRam, aRam;
DOUBLE percentFree;
Bunit unit = BunitMB;
BOOL showUsed;
};
INT parseArguments(INT, WCHAR **, boost::program_options::variables_map&, printInfoStruct&);
INT printOutput(printInfoStruct&);
INT check_memory(printInfoStruct&);
#endif // !CHECK_MEMORY_H

View File

@ -19,49 +19,42 @@
#define WIN32_LEAN_AND_MEAN #define WIN32_LEAN_AND_MEAN
#include <Windows.h> #include "plugins/thresholds.hpp"
#include <Pdh.h> #include <boost/program_options.hpp>
#include <Shlwapi.h> #include <boost/algorithm/string/replace.hpp>
#include <vector>
#include <map>
#include <windows.h>
#include <pdh.h>
#include <shlwapi.h>
#include <iostream> #include <iostream>
#include <pdhmsg.h> #include <pdhmsg.h>
#include <WinSock2.h> #include <winsock2.h>
#include <map> #include <iphlpapi.h>
#include <IPHlpApi.h>
#include "check_network.h"
#include "boost/algorithm/string/replace.hpp"
#define VERSION 1.2 #define VERSION 1.2
namespace po = boost::program_options; namespace po = boost::program_options;
static BOOL debug = FALSE; struct nInterface
static BOOL noisatap = FALSE;
INT wmain(INT argc, WCHAR **argv)
{ {
std::vector<nInterface> vInterfaces; std::wstring name;
std::map<std::wstring, std::wstring> mapNames; LONG BytesInSec, BytesOutSec;
printInfoStruct printInfo{}; nInterface(std::wstring p)
po::variables_map vm; : name(p)
{ }
};
INT ret = parseArguments(argc, argv, vm, printInfo); struct printInfoStruct
{
threshold warn;
threshold crit;
};
if (ret != -1) static bool l_Debug;
return ret; static bool l_NoISATAP;
if (!mapSystemNamesToFamiliarNames(mapNames)) static int parseArguments(int ac, WCHAR **av, po::variables_map& vm, printInfoStruct& printInfo)
return 3;
ret = check_network(vInterfaces);
if (ret != -1)
return ret;
return printOutput(printInfo, vInterfaces, mapNames);
}
INT parseArguments(INT ac, WCHAR **av, po::variables_map& vm, printInfoStruct& printInfo)
{ {
WCHAR namePath[MAX_PATH]; WCHAR namePath[MAX_PATH];
GetModuleFileName(NULL, namePath, MAX_PATH); GetModuleFileName(NULL, namePath, MAX_PATH);
@ -78,19 +71,19 @@ INT parseArguments(INT ac, WCHAR **av, po::variables_map& vm, printInfoStruct& p
("critical,c", po::wvalue<std::wstring>(), "critical value") ("critical,c", po::wvalue<std::wstring>(), "critical value")
; ;
po::basic_command_line_parser<WCHAR> parser(ac, av); po::wcommand_line_parser parser(ac, av);
try { try {
po::store( po::store(
parser parser
.options(desc) .options(desc)
.style( .style(
po::command_line_style::unix_style | po::command_line_style::unix_style |
po::command_line_style::allow_long_disguise) po::command_line_style::allow_long_disguise)
.run(), .run(),
vm); vm);
vm.notify(); vm.notify();
} catch (std::exception& e) { } catch (const std::exception& e) {
std::cout << e.what() << '\n' << desc << '\n'; std::cout << e.what() << '\n' << desc << '\n';
return 3; return 3;
} }
@ -144,7 +137,7 @@ INT parseArguments(INT ac, WCHAR **av, po::variables_map& vm, printInfoStruct& p
if (vm.count("warning")) { if (vm.count("warning")) {
try { try {
printInfo.warn = threshold(vm["warning"].as<std::wstring>()); printInfo.warn = threshold(vm["warning"].as<std::wstring>());
} catch (std::invalid_argument& e) { } catch (const std::invalid_argument& e) {
std::cout << e.what() << '\n'; std::cout << e.what() << '\n';
return 3; return 3;
} }
@ -152,28 +145,25 @@ INT parseArguments(INT ac, WCHAR **av, po::variables_map& vm, printInfoStruct& p
if (vm.count("critical")) { if (vm.count("critical")) {
try { try {
printInfo.crit = threshold(vm["critical"].as<std::wstring>()); printInfo.crit = threshold(vm["critical"].as<std::wstring>());
} catch (std::invalid_argument& e) { } catch (const std::invalid_argument& e) {
std::cout << e.what() << '\n'; std::cout << e.what() << '\n';
return 3; return 3;
} }
} }
if (vm.count("debug")) l_Debug = vm.count("debug") > 0;
debug = TRUE; l_NoISATAP = vm.count("noisatap") > 0;
if (vm.count("noisatap"))
noisatap = TRUE;
return -1; return -1;
} }
INT printOutput(printInfoStruct& printInfo, CONST std::vector<nInterface>& vInterfaces, CONST std::map<std::wstring, std::wstring>& mapNames) static int printOutput(printInfoStruct& printInfo, const std::vector<nInterface>& vInterfaces, const std::map<std::wstring, std::wstring>& mapNames)
{ {
if (debug) if (l_Debug)
std::wcout << L"Constructing output string" << '\n'; std::wcout << L"Constructing output string" << '\n';
long tIn = 0, tOut = 0; long tIn = 0, tOut = 0;
std::wstringstream tss, perfDataFirst; std::wstringstream tss;
state state = OK; state state = OK;
std::map<std::wstring, std::wstring>::const_iterator mapIt; std::map<std::wstring, std::wstring>::const_iterator mapIt;
@ -182,25 +172,23 @@ INT printOutput(printInfoStruct& printInfo, CONST std::vector<nInterface>& vInte
for (std::vector<nInterface>::const_iterator it = vInterfaces.begin(); it != vInterfaces.end(); ++it) { for (std::vector<nInterface>::const_iterator it = vInterfaces.begin(); it != vInterfaces.end(); ++it) {
tIn += it->BytesInSec; tIn += it->BytesInSec;
tOut += it->BytesOutSec; tOut += it->BytesOutSec;
if (debug) if (l_Debug)
std::wcout << "Getting friendly name of " << it->name << '\n'; std::wcout << "Getting friendly name of " << it->name << '\n';
mapIt = mapNames.find(it->name); mapIt = mapNames.find(it->name);
if (mapIt != mapNames.end()) { if (mapIt != mapNames.end()) {
if (debug) if (l_Debug)
std::wcout << "\tIs " << mapIt->second << '\n'; std::wcout << "\tIs " << mapIt->second << '\n';
wsFriendlyName = mapIt->second; wsFriendlyName = mapIt->second;
} else { } else {
if (debug) if (l_Debug)
std::wcout << "\tNo friendly name found, using adapter name\n"; std::wcout << "\tNo friendly name found, using adapter name\n";
wsFriendlyName = it->name; wsFriendlyName = it->name;
} }
if(wsFriendlyName.find(L"isatap") != std::wstring::npos && noisatap) { if (wsFriendlyName.find(L"isatap") != std::wstring::npos && l_NoISATAP) {
if (debug) if (l_Debug)
std::wcout << "\tSkipping isatap interface " << wsFriendlyName << "\n"; std::wcout << "\tSkipping isatap interface " << wsFriendlyName << "\n";
continue; continue;
} } else {
else
{
boost::algorithm::replace_all(wsFriendlyName, "'", "''"); boost::algorithm::replace_all(wsFriendlyName, "'", "''");
tss << L"\'" << wsFriendlyName << L"_in\'=" << it->BytesInSec << L"B \'" << wsFriendlyName << L"_out\'=" << it->BytesOutSec << L"B "; tss << L"\'" << wsFriendlyName << L"_in\'=" << it->BytesInSec << L"B \'" << wsFriendlyName << L"_out\'=" << it->BytesOutSec << L"B ";
} }
@ -211,77 +199,83 @@ INT printOutput(printInfoStruct& printInfo, CONST std::vector<nInterface>& vInte
if (printInfo.crit.rend(tIn + tOut)) if (printInfo.crit.rend(tIn + tOut))
state = CRITICAL; state = CRITICAL;
perfDataFirst << L"network=" << tIn + tOut << L"B;" << printInfo.warn.pString() << L";" << printInfo.crit.pString() << L";" << L"0; "; std::wcout << "NETWORK ";
switch (state) { switch (state) {
case OK: case OK:
std::wcout << L"NETWORK OK " << tIn + tOut << L"B/s | " << perfDataFirst.str() << tss.str() << '\n'; std::wcout << L"OK";
break; break;
case WARNING: case WARNING:
std::wcout << L"NETWORK WARNING " << tIn + tOut << L"B/s | " << perfDataFirst.str() << tss.str() << '\n'; std::wcout << L"WARNING";
break; break;
case CRITICAL: case CRITICAL:
std::wcout << L"NETWORK CRITICAL " << tIn + tOut << L"B/s | " << perfDataFirst.str() << tss.str() << '\n'; std::wcout << L"CRITICAL";
break; break;
} }
std::wcout << " " << tIn + tOut << L"B/s | "
<< L"network=" << tIn + tOut << L"B;" << printInfo.warn.pString() << L";" << printInfo.crit.pString() << L";" << L"0; "
<< tss.str() << '\n';
return state; return state;
} }
INT check_network(std::vector <nInterface>& vInterfaces) static int check_network(std::vector<nInterface>& vInterfaces)
{ {
CONST WCHAR *perfIn = L"\\Network Interface(*)\\Bytes Received/sec";
CONST WCHAR *perfOut = L"\\Network Interface(*)\\Bytes Sent/sec";
PDH_HQUERY phQuery = NULL; if (l_Debug)
PDH_HCOUNTER phCounterIn, phCounterOut;
DWORD dwBufferSizeIn = 0, dwBufferSizeOut = 0, dwItemCount = 0;
PDH_FMT_COUNTERVALUE_ITEM *pDisplayValuesIn = NULL, *pDisplayValuesOut = NULL;
PDH_STATUS err;
if (debug)
std::wcout << L"Creating Query and adding counters" << '\n'; std::wcout << L"Creating Query and adding counters" << '\n';
err = PdhOpenQuery(NULL, NULL, &phQuery); PDH_FMT_COUNTERVALUE_ITEM *pDisplayValuesIn = NULL, *pDisplayValuesOut = NULL;
PDH_HQUERY phQuery;
PDH_STATUS err = PdhOpenQuery(NULL, NULL, &phQuery);
if (!SUCCEEDED(err)) if (!SUCCEEDED(err))
goto die; goto die;
const WCHAR *perfIn = L"\\Network Interface(*)\\Bytes Received/sec";
PDH_HCOUNTER phCounterIn;
err = PdhAddEnglishCounter(phQuery, perfIn, NULL, &phCounterIn); err = PdhAddEnglishCounter(phQuery, perfIn, NULL, &phCounterIn);
if (!SUCCEEDED(err)) if (!SUCCEEDED(err))
goto die; goto die;
const WCHAR *perfOut = L"\\Network Interface(*)\\Bytes Sent/sec";
PDH_HCOUNTER phCounterOut;
err = PdhAddEnglishCounter(phQuery, perfOut, NULL, &phCounterOut); err = PdhAddEnglishCounter(phQuery, perfOut, NULL, &phCounterOut);
if (!SUCCEEDED(err)) if (!SUCCEEDED(err))
goto die; goto die;
if (debug) if (l_Debug)
std::wcout << L"Collecting first batch of query data" << '\n'; std::wcout << L"Collecting first batch of query data" << '\n';
err = PdhCollectQueryData(phQuery); err = PdhCollectQueryData(phQuery);
if (!SUCCEEDED(err)) if (!SUCCEEDED(err))
goto die; goto die;
if (debug) if (l_Debug)
std::wcout << L"Sleep for one second" << '\n'; std::wcout << L"Sleep for one second" << '\n';
Sleep(1000); Sleep(1000);
if (debug) if (l_Debug)
std::wcout << L"Collecting second batch of query data" << '\n'; std::wcout << L"Collecting second batch of query data" << '\n';
err = PdhCollectQueryData(phQuery); err = PdhCollectQueryData(phQuery);
if (!SUCCEEDED(err)) if (!SUCCEEDED(err))
goto die; goto die;
if (debug) if (l_Debug)
std::wcout << L"Creating formatted counter arrays" << '\n'; std::wcout << L"Creating formatted counter arrays" << '\n';
DWORD dwItemCount;
DWORD dwBufferSizeIn = 0;
err = PdhGetFormattedCounterArray(phCounterIn, PDH_FMT_LONG, &dwBufferSizeIn, &dwItemCount, pDisplayValuesIn); err = PdhGetFormattedCounterArray(phCounterIn, PDH_FMT_LONG, &dwBufferSizeIn, &dwItemCount, pDisplayValuesIn);
if (err == PDH_MORE_DATA || SUCCEEDED(err)) if (err == PDH_MORE_DATA || SUCCEEDED(err))
pDisplayValuesIn = reinterpret_cast<PDH_FMT_COUNTERVALUE_ITEM*>(new BYTE[dwItemCount*dwBufferSizeIn]); pDisplayValuesIn = reinterpret_cast<PDH_FMT_COUNTERVALUE_ITEM*>(new BYTE[dwItemCount*dwBufferSizeIn]);
else else
goto die; goto die;
DWORD dwBufferSizeOut = 0;
err = PdhGetFormattedCounterArray(phCounterOut, PDH_FMT_LONG, &dwBufferSizeOut, &dwItemCount, pDisplayValuesOut); err = PdhGetFormattedCounterArray(phCounterOut, PDH_FMT_LONG, &dwBufferSizeOut, &dwItemCount, pDisplayValuesOut);
if (err == PDH_MORE_DATA || SUCCEEDED(err)) if (err == PDH_MORE_DATA || SUCCEEDED(err))
pDisplayValuesOut = reinterpret_cast<PDH_FMT_COUNTERVALUE_ITEM*>(new BYTE[dwItemCount*dwBufferSizeIn]); pDisplayValuesOut = reinterpret_cast<PDH_FMT_COUNTERVALUE_ITEM*>(new BYTE[dwItemCount*dwBufferSizeIn]);
@ -296,48 +290,42 @@ INT check_network(std::vector <nInterface>& vInterfaces)
if (!SUCCEEDED(err)) if (!SUCCEEDED(err))
goto die; goto die;
if (debug) if (l_Debug)
std::wcout << L"Going over counter array" << '\n'; std::wcout << L"Going over counter array" << '\n';
for (DWORD i = 0; i < dwItemCount; i++) { for (DWORD i = 0; i < dwItemCount; i++) {
nInterface *iface = new nInterface(std::wstring(pDisplayValuesIn[i].szName)); nInterface iface{pDisplayValuesIn[i].szName};
iface->BytesInSec = pDisplayValuesIn[i].FmtValue.longValue; iface.BytesInSec = pDisplayValuesIn[i].FmtValue.longValue;
iface->BytesOutSec = pDisplayValuesOut[i].FmtValue.longValue; iface.BytesOutSec = pDisplayValuesOut[i].FmtValue.longValue;
vInterfaces.push_back(*iface); vInterfaces.push_back(iface);
if (debug)
if (l_Debug)
std::wcout << L"Collected interface " << pDisplayValuesIn[i].szName << '\n'; std::wcout << L"Collected interface " << pDisplayValuesIn[i].szName << '\n';
} }
if (debug)
if (l_Debug)
std::wcout << L"Finished collection. Cleaning up and returning" << '\n'; std::wcout << L"Finished collection. Cleaning up and returning" << '\n';
if (phQuery) if (phQuery)
PdhCloseQuery(phQuery); PdhCloseQuery(phQuery);
if (pDisplayValuesIn)
delete reinterpret_cast<PDH_FMT_COUNTERVALUE_ITEM*>(pDisplayValuesIn); delete reinterpret_cast<BYTE *>(pDisplayValuesIn);
if (pDisplayValuesOut) delete reinterpret_cast<BYTE *>(pDisplayValuesOut);
delete reinterpret_cast<PDH_FMT_COUNTERVALUE_ITEM*>(pDisplayValuesOut);
return -1; return -1;
die: die:
die(err); printErrorInfo(err);
if (phQuery) if (phQuery)
PdhCloseQuery(phQuery); PdhCloseQuery(phQuery);
if (pDisplayValuesIn)
delete reinterpret_cast<PDH_FMT_COUNTERVALUE_ITEM*>(pDisplayValuesIn); delete reinterpret_cast<BYTE *>(pDisplayValuesIn);
if (pDisplayValuesOut) delete reinterpret_cast<BYTE *>(pDisplayValuesOut);
delete reinterpret_cast<PDH_FMT_COUNTERVALUE_ITEM*>(pDisplayValuesOut);
return 3; return 3;
} }
BOOL mapSystemNamesToFamiliarNames(std::map<std::wstring, std::wstring>& mapNames) static bool mapSystemNamesToFamiliarNames(std::map<std::wstring, std::wstring>& mapNames)
{ {
DWORD dwSize = 0, dwRetVal = 0;
ULONG family = AF_UNSPEC, flags = GAA_FLAG_INCLUDE_PREFIX,
outBufLen = 0, Iterations = 0;
LPVOID lpMsgBuf = NULL;
PIP_ADAPTER_ADDRESSES pAddresses = NULL;
PIP_ADAPTER_ADDRESSES pCurrAddresses = NULL;
/* /*
PIP_ADAPTER_UNICAST_ADDRESS pUnicast = NULL; PIP_ADAPTER_UNICAST_ADDRESS pUnicast = NULL;
PIP_ADAPTER_ANYCAST_ADDRESS pAnycast = NULL; PIP_ADAPTER_ANYCAST_ADDRESS pAnycast = NULL;
@ -345,15 +333,20 @@ BOOL mapSystemNamesToFamiliarNames(std::map<std::wstring, std::wstring>& mapName
PIP_ADAPTER_DNS_SERVER_ADDRESS pDnsServer = NULL; PIP_ADAPTER_DNS_SERVER_ADDRESS pDnsServer = NULL;
PIP_ADAPTER_PREFIX pPrefix = NULL; PIP_ADAPTER_PREFIX pPrefix = NULL;
*/ */
outBufLen = 15000; //15KB as suggestet by msdn of GetAdaptersAddresses ULONG outBufLen = 15000; //15KB as suggestet by msdn of GetAdaptersAddresses
if (debug) if (l_Debug)
std::wcout << "Mapping adapter system names to friendly names\n"; std::wcout << "Mapping adapter system names to friendly names\n";
PIP_ADAPTER_ADDRESSES pAddresses;
unsigned int Iterations = 0;
DWORD dwRetVal = 0;
do { do {
pAddresses = reinterpret_cast<PIP_ADAPTER_ADDRESSES>(new BYTE[outBufLen]); pAddresses = reinterpret_cast<PIP_ADAPTER_ADDRESSES>(new BYTE[outBufLen]);
dwRetVal = GetAdaptersAddresses(family, flags, NULL, pAddresses, &outBufLen); dwRetVal = GetAdaptersAddresses(AF_UNSPEC, GAA_FLAG_INCLUDE_PREFIX, NULL, pAddresses, &outBufLen);
if (dwRetVal == ERROR_BUFFER_OVERFLOW) { if (dwRetVal == ERROR_BUFFER_OVERFLOW) {
delete[]pAddresses; delete[]pAddresses;
@ -365,23 +358,38 @@ BOOL mapSystemNamesToFamiliarNames(std::map<std::wstring, std::wstring>& mapName
if (dwRetVal != NO_ERROR) { if (dwRetVal != NO_ERROR) {
std::wcout << "Failed to collect friendly adapter names\n"; std::wcout << "Failed to collect friendly adapter names\n";
delete[]pAddresses; delete[]pAddresses;
return FALSE; return false;
} }
pCurrAddresses = pAddresses; for (PIP_ADAPTER_ADDRESSES pCurrAddresses = pAddresses; pCurrAddresses; pCurrAddresses = pCurrAddresses->Next) {
std::wstringstream wssAdapterName; if (l_Debug)
std::wstringstream wssFriendlyName; std::wcout << "Got: " << pCurrAddresses->Description << " -- " << pCurrAddresses->FriendlyName << '\n';
for (pCurrAddresses = pAddresses; pCurrAddresses; pCurrAddresses = pCurrAddresses->Next) {
wssAdapterName.str(std::wstring());
wssFriendlyName.str(std::wstring());
wssAdapterName << pCurrAddresses->Description;
wssFriendlyName << pCurrAddresses->FriendlyName;
if (debug)
std::wcout << "Got: " << wssAdapterName.str() << " -- " << wssFriendlyName.str() << '\n';
mapNames.insert(std::pair<std::wstring, std::wstring>(wssAdapterName.str(), wssFriendlyName.str())); mapNames[pCurrAddresses->Description] = pCurrAddresses->FriendlyName;
} }
delete[]pAddresses; delete[]pAddresses;
return TRUE; return true;
}
int wmain(int argc, WCHAR **argv)
{
std::vector<nInterface> vInterfaces;
std::map<std::wstring, std::wstring> mapNames;
printInfoStruct printInfo;
po::variables_map vm;
int ret = parseArguments(argc, argv, vm, printInfo);
if (ret != -1)
return ret;
if (!mapSystemNamesToFamiliarNames(mapNames))
return 3;
ret = check_network(vInterfaces);
if (ret != -1)
return ret;
return printOutput(printInfo, vInterfaces, mapNames);
} }

View File

@ -1,47 +0,0 @@
/******************************************************************************
* Icinga 2 *
* Copyright (C) 2012-2018 Icinga Development Team (https://www.icinga.com/) *
* *
* This program is free software; you can redistribute it and/or *
* modify it under the terms of the GNU General Public License *
* as published by the Free Software Foundation; either version 2 *
* of the License, or (at your option) any later version. *
* *
* This program is distributed in the hope that it will be useful, *
* but WITHOUT ANY WARRANTY; without even the implied warranty of *
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
* GNU General Public License for more details. *
* *
* You should have received a copy of the GNU General Public License *
* along with this program; if not, write to the Free Software Foundation *
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA. *
******************************************************************************/
#ifndef CHECK_NETWORK_H
#define CHECK_NETWORK_H
#include <vector>
#include "thresholds.h"
#include "boost/program_options.hpp"
struct nInterface
{
std::wstring name;
LONG BytesInSec, BytesOutSec;
nInterface(std::wstring p)
: name(p)
{
}
};
struct printInfoStruct
{
threshold warn, crit;
};
INT parseArguments(INT, WCHAR **, boost::program_options::variables_map&, printInfoStruct&);
INT printOutput(printInfoStruct&, CONST std::vector<nInterface>&, CONST std::map<std::wstring, std::wstring>&);
INT check_network(std::vector<nInterface>&);
BOOL mapSystemNamesToFamiliarNames(std::map<std::wstring, std::wstring>&);
#endif // !CHECK_NETWORK_H

View File

@ -1,21 +1,21 @@
/****************************************************************************** /******************************************************************************
* Icinga 2 * * Icinga 2 *
* Copyright (C) 2012-2018 Icinga Development Team (https://www.icinga.com/) * * Copyright (C) 2012-2018 Icinga Development Team (https://www.icinga.com/) *
* * * *
* This program is free software; you can redistribute it and/or * * This program is free software; you can redistribute it and/or *
* modify it under the terms of the GNU General Public License * * modify it under the terms of the GNU General Public License *
* as published by the Free Software Foundation; either version 2 * * as published by the Free Software Foundation; either version 2 *
* of the License, or (at your option) any later version. * * of the License, or (at your option) any later version. *
* * * *
* This program is distributed in the hope that it will be useful, * * This program is distributed in the hope that it will be useful, *
* but WITHOUT ANY WARRANTY; without even the implied warranty of * * but WITHOUT ANY WARRANTY; without even the implied warranty of *
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
* GNU General Public License for more details. * * GNU General Public License for more details. *
* * * *
* You should have received a copy of the GNU General Public License * * You should have received a copy of the GNU General Public License *
* along with this program; if not, write to the Free Software Foundation * * along with this program; if not, write to the Free Software Foundation *
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA. * * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA. *
******************************************************************************/ ******************************************************************************/
#define VERSION "1.0.0" #define VERSION "1.0.0"
@ -33,7 +33,7 @@
using namespace icinga; using namespace icinga;
namespace po = boost::program_options; namespace po = boost::program_options;
bool l_Debug = false; static bool l_Debug;
/* /*
* This function is called by an 'HttpRequest' once the server answers. After doing a short check on the 'response' it * This function is called by an 'HttpRequest' once the server answers. After doing a short check on the 'response' it
@ -245,7 +245,7 @@ int main(int argc, char **argv)
("query,q", po::value<std::string>()->required(), "REQUIRED: NSCP API Query endpoint") ("query,q", po::value<std::string>()->required(), "REQUIRED: NSCP API Query endpoint")
("arguments,a", po::value<std::vector<std::string>>()->multitoken(), "NSCP API Query arguments for the endpoint"); ("arguments,a", po::value<std::vector<std::string>>()->multitoken(), "NSCP API Query arguments for the endpoint");
po::basic_command_line_parser<char> parser(argc, argv); po::command_line_parser parser(argc, argv);
try { try {
po::store( po::store(
@ -271,14 +271,12 @@ int main(int argc, char **argv)
} }
vm.notify(); vm.notify();
} catch (std::exception& e) { } catch (const std::exception& e) {
std::cout << e.what() << '\n' << desc << '\n'; std::cout << e.what() << '\n' << desc << '\n';
Application::Exit(3); Application::Exit(3);
} }
if (vm.count("debug")) { l_Debug = vm.count("debug") > 0;
l_Debug = true;
}
// Create the URL string and escape certain characters since Url() follows RFC 3986 // Create the URL string and escape certain characters since Url() follows RFC 3986
String endpoint = "/query/" + vm["query"].as<std::string>(); String endpoint = "/query/" + vm["query"].as<std::string>();

View File

@ -1,56 +1,46 @@
/****************************************************************************** /******************************************************************************
* Icinga 2 * * Icinga 2 *
* Copyright (C) 2012-2018 Icinga Development Team (https://www.icinga.com/) * * Copyright (C) 2012-2018 Icinga Development Team (https://www.icinga.com/) *
* * * *
* This program is free software; you can redistribute it and/or * * This program is free software; you can redistribute it and/or *
* modify it under the terms of the GNU General Public License * * modify it under the terms of the GNU General Public License *
* as published by the Free Software Foundation; either version 2 * * as published by the Free Software Foundation; either version 2 *
* of the License, or (at your option) any later version. * * of the License, or (at your option) any later version. *
* * * *
* This program is distributed in the hope that it will be useful, * * This program is distributed in the hope that it will be useful, *
* but WITHOUT ANY WARRANTY; without even the implied warranty of * * but WITHOUT ANY WARRANTY; without even the implied warranty of *
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
* GNU General Public License for more details. * * GNU General Public License for more details. *
* * * *
* You should have received a copy of the GNU General Public License * * You should have received a copy of the GNU General Public License *
* along with this program; if not, write to the Free Software Foundation * * along with this program; if not, write to the Free Software Foundation *
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA. * * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA. *
******************************************************************************/ ******************************************************************************/
#include <Shlwapi.h> #include "plugins/thresholds.hpp"
#include <boost/program_options.hpp>
#include <iostream> #include <iostream>
#include <vector> #include <vector>
#include <windows.h>
#include "check_perfmon.h" #include <pdh.h>
#include <pdhmsg.h>
#include <shlwapi.h>
#define VERSION 1.0 #define VERSION 1.0
namespace po = boost::program_options; namespace po = boost::program_options;
INT wmain(INT argc, WCHAR **argv) struct printInfoStruct
{ {
po::variables_map variables_map; threshold tWarn;
printInfoStruct stPrintInfo; threshold tCrit;
if (!ParseArguments(argc, argv, variables_map, stPrintInfo)) std::wstring wsFullPath;
return 3; double dValue;
DWORD dwPerformanceWait = 1000;
DWORD dwRequestedType = PDH_FMT_DOUBLE;
};
if (variables_map.count("print-objects")) { static bool parseArguments(const int ac, WCHAR **av, po::variables_map& vm, printInfoStruct& printInfo)
PrintObjects();
return 0;
}
if (variables_map.count("print-object-info")) {
PrintObjectInfo(stPrintInfo);
return 0;
}
if (QueryPerfData(stPrintInfo))
return PrintOutput(variables_map, stPrintInfo);
else
return 3;
}
BOOL ParseArguments(CONST INT ac, WCHAR **av, po::variables_map& vm, printInfoStruct& printInfo)
{ {
WCHAR szNamePath[MAX_PATH + 1]; WCHAR szNamePath[MAX_PATH + 1];
GetModuleFileName(NULL, szNamePath, MAX_PATH); GetModuleFileName(NULL, szNamePath, MAX_PATH);
@ -70,26 +60,26 @@ BOOL ParseArguments(CONST INT ac, WCHAR **av, po::variables_map& vm, printInfoSt
("perf-syntax", po::wvalue<std::wstring>(), "Use this string as name for the performance counter (graphite compatibility)") ("perf-syntax", po::wvalue<std::wstring>(), "Use this string as name for the performance counter (graphite compatibility)")
; ;
po::basic_command_line_parser<wchar_t> parser(ac, av); po::wcommand_line_parser parser(ac, av);
try { try {
po::store( po::store(
parser parser
.options(desc) .options(desc)
.style( .style(
po::command_line_style::unix_style | po::command_line_style::unix_style |
po::command_line_style::allow_long_disguise) po::command_line_style::allow_long_disguise)
.run(), .run(),
vm); vm);
vm.notify(); vm.notify();
} catch (std::exception& e) { } catch (const std::exception& e) {
std::cout << e.what() << '\n' << desc << '\n'; std::cout << e.what() << '\n' << desc << '\n';
return FALSE; return false;
} }
if (vm.count("version")) { if (vm.count("version")) {
std::wcout << "Version: " << VERSION << '\n'; std::wcout << "Version: " << VERSION << '\n';
return FALSE; return false;
} }
if (vm.count("help")) { if (vm.count("help")) {
@ -110,24 +100,24 @@ BOOL ParseArguments(CONST INT ac, WCHAR **av, po::variables_map& vm, printInfoSt
L" 2\tCRITICAL,\n\tThe critical threshold was broken\n" L" 2\tCRITICAL,\n\tThe critical threshold was broken\n"
L" 3\tUNKNOWN, \n\tNo check could be performed\n\n" L" 3\tUNKNOWN, \n\tNo check could be performed\n\n"
, szProgName); , szProgName);
return 0; return false;
} }
if (vm.count("warning")) { if (vm.count("warning")) {
try { try {
printInfo.tWarn = threshold(vm["warning"].as<std::wstring>()); printInfo.tWarn = threshold(vm["warning"].as<std::wstring>());
} catch (std::invalid_argument& e) { } catch (const std::invalid_argument& e) {
std::wcout << e.what() << '\n'; std::wcout << e.what() << '\n';
return FALSE; return false;
} }
} }
if (vm.count("critical")) { if (vm.count("critical")) {
try { try {
printInfo.tCrit = threshold(vm["critical"].as<std::wstring>()); printInfo.tCrit = threshold(vm["critical"].as<std::wstring>());
} catch (std::invalid_argument& e) { } catch (const std::invalid_argument& e) {
std::wcout << e.what() << '\n'; std::wcout << e.what() << '\n';
return FALSE; return false;
} }
} }
@ -138,7 +128,7 @@ BOOL ParseArguments(CONST INT ac, WCHAR **av, po::variables_map& vm, printInfoSt
printInfo.dwRequestedType = PDH_FMT_LONG; printInfo.dwRequestedType = PDH_FMT_LONG;
else if (vm["fmt-countertype"].as<std::wstring>().compare(L"double")) { else if (vm["fmt-countertype"].as<std::wstring>().compare(L"double")) {
std::wcout << "Unknown value type " << vm["fmt-countertype"].as<std::wstring>() << '\n'; std::wcout << "Unknown value type " << vm["fmt-countertype"].as<std::wstring>() << '\n';
return FALSE; return false;
} }
} }
@ -148,46 +138,33 @@ BOOL ParseArguments(CONST INT ac, WCHAR **av, po::variables_map& vm, printInfoSt
if (vm.count("performance-wait")) if (vm.count("performance-wait"))
printInfo.dwPerformanceWait = vm["performance-wait"].as<DWORD>(); printInfo.dwPerformanceWait = vm["performance-wait"].as<DWORD>();
return TRUE; return true;
} }
BOOL GetIntstancesAndCountersOfObject(CONST std::wstring wsObject, static bool getInstancesAndCountersOfObject(const std::wstring& wsObject,
std::vector<std::wstring>& vecInstances, std::vector<std::wstring>& vecCounters) std::vector<std::wstring>& vecInstances, std::vector<std::wstring>& vecCounters)
{ {
LPWSTR szDataSource = NULL, szMachineName = NULL,
mszCounterList = NULL, mszInstanceList = NULL;
DWORD dwCounterListLength = 0, dwInstanceListLength = 0; DWORD dwCounterListLength = 0, dwInstanceListLength = 0;
std::wstringstream wssInstanceName, wssCounterName; if (PdhEnumObjectItems(NULL, NULL, wsObject.c_str(),
LPWSTR szObjectName = new WCHAR[wsObject.length() + 1]; NULL, &dwCounterListLength, NULL,
StrCpyW(szObjectName, wsObject.c_str()); &dwInstanceListLength, PERF_DETAIL_WIZARD, 0) != PDH_MORE_DATA)
return false;
PDH_STATUS status = std::vector<WCHAR> mszCounterList(dwCounterListLength + 1);
PdhEnumObjectItems(szDataSource, szMachineName, szObjectName, std::vector<WCHAR> mszInstanceList(dwInstanceListLength + 1);
mszCounterList, &dwCounterListLength, mszInstanceList,
&dwInstanceListLength, PERF_DETAIL_WIZARD, 0);
if (status != PDH_MORE_DATA) { if (FAILED(PdhEnumObjectItems(NULL, NULL, wsObject.c_str(),
delete[]szObjectName; mszCounterList.data(), &dwCounterListLength, mszInstanceList.data(),
return FALSE; &dwInstanceListLength, PERF_DETAIL_WIZARD, 0))) {
} return false;
mszCounterList = new WCHAR[dwCounterListLength + 1];
mszInstanceList = new WCHAR[dwInstanceListLength + 1];
status = PdhEnumObjectItems(szDataSource, szMachineName, szObjectName,
mszCounterList, &dwCounterListLength, mszInstanceList,
&dwInstanceListLength, PERF_DETAIL_WIZARD, 0);
if (FAILED(status)) {
delete[]mszCounterList;
delete[]mszInstanceList;
delete[]szObjectName;
return FALSE;
} }
if (dwInstanceListLength) { if (dwInstanceListLength) {
for (DWORD c = 0; c < dwInstanceListLength-1; ++c) { std::wstringstream wssInstanceName;
// XXX: is the "- 1" correct?
for (DWORD c = 0; c < dwInstanceListLength - 1; ++c) {
if (mszInstanceList[c]) if (mszInstanceList[c])
wssInstanceName << mszInstanceList[c]; wssInstanceName << mszInstanceList[c];
else { else {
@ -198,41 +175,66 @@ BOOL GetIntstancesAndCountersOfObject(CONST std::wstring wsObject,
} }
if (dwCounterListLength) { if (dwCounterListLength) {
for (DWORD c = 0; c < dwCounterListLength-1; ++c) { std::wstringstream wssCounterName;
if (mszCounterList[c]) {
// XXX: is the "- 1" correct?
for (DWORD c = 0; c < dwCounterListLength - 1; ++c) {
if (mszCounterList[c])
wssCounterName << mszCounterList[c]; wssCounterName << mszCounterList[c];
} else { else {
vecCounters.push_back(wssCounterName.str()); vecCounters.push_back(wssCounterName.str());
wssCounterName.str(L""); wssCounterName.str(L"");
} }
} }
} }
delete[]mszCounterList; return true;
delete[]mszInstanceList;
delete[]szObjectName;
return TRUE;
} }
VOID PrintObjects() static void printPDHError(PDH_STATUS status)
{
HMODULE hPdhLibrary = NULL;
LPWSTR pMessage = NULL;
hPdhLibrary = LoadLibrary(L"pdh.dll");
if (!hPdhLibrary) {
std::wcout << "LoadLibrary failed with " << GetLastError() << '\n';
return;
}
if (!FormatMessage(FORMAT_MESSAGE_FROM_HMODULE | FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_ARGUMENT_ARRAY,
hPdhLibrary, status, 0, (LPWSTR)&pMessage, 0, NULL)) {
FreeLibrary(hPdhLibrary);
std::wcout << "Format message failed with " << std::hex << GetLastError() << '\n';
return;
}
FreeLibrary(hPdhLibrary);
std::wcout << pMessage << '\n';
LocalFree(pMessage);
}
static void printObjects()
{ {
LPWSTR szDataSource = NULL, szMachineName = NULL, mszObjectList = NULL;
DWORD dwBufferLength = 0; DWORD dwBufferLength = 0;
PDH_STATUS status = PDH_STATUS status = PdhEnumObjects(NULL, NULL, NULL,
PdhEnumObjects(szDataSource, szMachineName, mszObjectList,
&dwBufferLength, PERF_DETAIL_WIZARD, FALSE); &dwBufferLength, PERF_DETAIL_WIZARD, FALSE);
//HEX HEX! Only a Magicians gets all the info he wants, and only Microsoft knows what that means //HEX HEX! Only a Magicians gets all the info he wants, and only Microsoft knows what that means
if (status != PDH_MORE_DATA) if (status != PDH_MORE_DATA) {
goto die; printPDHError(status);
return;
}
mszObjectList = new WCHAR[dwBufferLength + 2]; std::vector<WCHAR> mszObjectList(dwBufferLength + 2);
status = PdhEnumObjects(szDataSource, szMachineName, mszObjectList, status = PdhEnumObjects(NULL, NULL, mszObjectList.data(),
&dwBufferLength, PERF_DETAIL_WIZARD, FALSE); &dwBufferLength, PERF_DETAIL_WIZARD, FALSE);
if (FAILED(status)) if (FAILED(status)) {
goto die; printPDHError(status);
return;
}
DWORD c = 0; DWORD c = 0;
@ -242,16 +244,9 @@ VOID PrintObjects()
else else
std::wcout << mszObjectList[c]; std::wcout << mszObjectList[c];
} }
delete[]mszObjectList;
return;
die:
FormatPDHError(status);
delete[]mszObjectList;
} }
VOID PrintObjectInfo(CONST printInfoStruct& pI) static void printObjectInfo(const printInfoStruct& pI)
{ {
if (pI.wsFullPath.empty()) { if (pI.wsFullPath.empty()) {
std::wcout << "No object given!\n"; std::wcout << "No object given!\n";
@ -260,7 +255,7 @@ VOID PrintObjectInfo(CONST printInfoStruct& pI)
std::vector<std::wstring> vecInstances, vecCounters; std::vector<std::wstring> vecInstances, vecCounters;
if (!GetIntstancesAndCountersOfObject(pI.wsFullPath, vecInstances, vecCounters)) { if (!getInstancesAndCountersOfObject(pI.wsFullPath, vecInstances, vecCounters)) {
std::wcout << "Could not enumerate instances and counters of " << pI.wsFullPath << '\n' std::wcout << "Could not enumerate instances and counters of " << pI.wsFullPath << '\n'
<< "Make sure it exists!\n"; << "Make sure it exists!\n";
return; return;
@ -270,10 +265,8 @@ VOID PrintObjectInfo(CONST printInfoStruct& pI)
if (vecInstances.empty()) if (vecInstances.empty())
std::wcout << "> Has no instances\n"; std::wcout << "> Has no instances\n";
else { else {
for (std::vector<std::wstring>::iterator it = vecInstances.begin(); for (const auto& instance : vecInstances)
it != vecInstances.end(); ++it) { std::wcout << "> " << instance << '\n';
std::wcout << "> " << *it << '\n';
}
} }
std::wcout << std::endl; std::wcout << std::endl;
@ -281,26 +274,25 @@ VOID PrintObjectInfo(CONST printInfoStruct& pI)
if (vecCounters.empty()) if (vecCounters.empty())
std::wcout << "> Has no counters\n"; std::wcout << "> Has no counters\n";
else { else {
for (std::vector<std::wstring>::iterator it = vecCounters.begin(); for (const auto& counter : vecCounters)
it != vecCounters.end(); ++it) { std::wcout << "> " << counter << "\n";
std::wcout << "> " << *it << '\n';
}
} }
std::wcout << std::endl; std::wcout << std::endl;
} }
BOOL QueryPerfData(printInfoStruct& pI) bool QueryPerfData(printInfoStruct& pI)
{ {
PDH_HQUERY hQuery = NULL; PDH_HQUERY hQuery = NULL;
PDH_HCOUNTER hCounter = NULL; PDH_HCOUNTER hCounter = NULL;
PDH_FMT_COUNTERVALUE_ITEM *pDisplayValues = NULL;
DWORD dwBufferSize = 0, dwItemCount = 0; DWORD dwBufferSize = 0, dwItemCount = 0;
if (pI.wsFullPath.empty()) { if (pI.wsFullPath.empty()) {
std::wcout << "No performance counter path given!\n"; std::wcout << "No performance counter path given!\n";
return FALSE; return false;
} }
PDH_FMT_COUNTERVALUE_ITEM *pDisplayValues = NULL;
PDH_STATUS status = PdhOpenQuery(NULL, NULL, &hQuery); PDH_STATUS status = PdhOpenQuery(NULL, NULL, &hQuery);
if (FAILED(status)) if (FAILED(status))
goto die; goto die;
@ -314,16 +306,16 @@ BOOL QueryPerfData(printInfoStruct& pI)
goto die; goto die;
/* /*
* Most counters need two queries to provide a value. * Most counters need two queries to provide a value.
* Those which need only one will return the second. * Those which need only one will return the second.
*/ */
Sleep(pI.dwPerformanceWait); Sleep(pI.dwPerformanceWait);
status = PdhCollectQueryData(hQuery); status = PdhCollectQueryData(hQuery);
if (FAILED(status)) if (FAILED(status))
goto die; goto die;
status = PdhGetFormattedCounterArray(hCounter, pI.dwRequestedType, &dwBufferSize, &dwItemCount, pDisplayValues); status = PdhGetFormattedCounterArray(hCounter, pI.dwRequestedType, &dwBufferSize, &dwItemCount, NULL);
if (status != PDH_MORE_DATA) if (status != PDH_MORE_DATA)
goto die; goto die;
@ -333,8 +325,7 @@ BOOL QueryPerfData(printInfoStruct& pI)
if (FAILED(status)) if (FAILED(status))
goto die; goto die;
switch (pI.dwRequestedType) switch (pI.dwRequestedType) {
{
case (PDH_FMT_LONG): case (PDH_FMT_LONG):
pI.dValue = pDisplayValues[0].FmtValue.longValue; pI.dValue = pDisplayValues[0].FmtValue.longValue;
break; break;
@ -348,23 +339,22 @@ BOOL QueryPerfData(printInfoStruct& pI)
delete[]pDisplayValues; delete[]pDisplayValues;
return TRUE; return true;
die: die:
FormatPDHError(status); printPDHError(status);
delete[]pDisplayValues; delete[]pDisplayValues;
return FALSE; return false;
} }
INT PrintOutput(CONST po::variables_map& vm, printInfoStruct& pi) static int printOutput(const po::variables_map& vm, printInfoStruct& pi)
{ {
std::wstringstream wssPerfData; std::wstringstream wssPerfData;
if (vm.count("perf-syntax")) { if (vm.count("perf-syntax"))
wssPerfData << "\"" << vm["perf-syntax"].as<std::wstring>() << "\"="; wssPerfData << "\"" << vm["perf-syntax"].as<std::wstring>() << "\"=";
} else { else
wssPerfData << "\"" << pi.wsFullPath << "\"="; wssPerfData << "\"" << pi.wsFullPath << "\"=";
}
wssPerfData << pi.dValue << ';' << pi.tWarn.pString() << ';' << pi.tCrit.pString() << ";;"; wssPerfData << pi.dValue << ';' << pi.tWarn.pString() << ';' << pi.tCrit.pString() << ";;";
@ -385,23 +375,25 @@ INT PrintOutput(CONST po::variables_map& vm, printInfoStruct& pi)
return 0; return 0;
} }
VOID FormatPDHError(PDH_STATUS status) int wmain(int argc, WCHAR **argv)
{ {
HANDLE hPdhLibrary = NULL; po::variables_map variables_map;
LPWSTR pMessage = NULL; printInfoStruct stPrintInfo;
if (!parseArguments(argc, argv, variables_map, stPrintInfo))
return 3;
hPdhLibrary = LoadLibrary(L"pdh.dll"); if (variables_map.count("print-objects")) {
if (NULL == hPdhLibrary) { printObjects();
std::wcout << "LoadLibrary failed with " << GetLastError() << '\n'; return 0;
return;
} }
if (!FormatMessage(FORMAT_MESSAGE_FROM_HMODULE | FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_ARGUMENT_ARRAY, if (variables_map.count("print-object-info")) {
hPdhLibrary, status, 0, (LPWSTR)&pMessage, 0, NULL)) { printObjectInfo(stPrintInfo);
std::wcout << "Format message failed with " << std::hex << GetLastError() << '\n'; return 0;
return;
} }
std::wcout << pMessage << '\n'; if (QueryPerfData(stPrintInfo))
LocalFree(pMessage); return printOutput(variables_map, stPrintInfo);
else
return 3;
} }

View File

@ -1,48 +0,0 @@
/******************************************************************************
* Icinga 2 *
* Copyright (C) 2012-2018 Icinga Development Team (https://www.icinga.com/) *
* *
* This program is free software; you can redistribute it and/or *
* modify it under the terms of the GNU General Public License *
* as published by the Free Software Foundation; either version 2 *
* of the License, or (at your option) any later version. *
* *
* This program is distributed in the hope that it will be useful, *
* but WITHOUT ANY WARRANTY; without even the implied warranty of *
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
* GNU General Public License for more details. *
* *
* You should have received a copy of the GNU General Public License *
* along with this program; if not, write to the Free Software Foundation *
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA. *
******************************************************************************/
#ifndef CHECK_PERFMON_H
#define CHECK_PERFMON_H
#include <Windows.h>
#include <Pdh.h>
#include <pdhmsg.h>
#include "thresholds.h"
#include "boost/program_options.hpp"
struct printInfoStruct
{
threshold tWarn, tCrit;
std::wstring wsFullPath;
DOUBLE dValue;
DWORD dwPerformanceWait = 1000,
dwRequestedType = PDH_FMT_DOUBLE;
};
BOOL ParseArguments(CONST INT, WCHAR **, boost::program_options::variables_map&, printInfoStruct&);
BOOL GetIntstancesAndCountersOfObject(CONST std::wstring, std::vector<std::wstring>&, std::vector<std::wstring>&);
VOID PrintObjects();
VOID PrintObjectInfo(CONST printInfoStruct&);
INT QueryPerfData(printInfoStruct&);
INT PrintOutput(CONST boost::program_options::variables_map&, printInfoStruct&);
VOID FormatPDHError(PDH_STATUS);
#endif // !CHECK_PERFMON_H

View File

@ -1,76 +1,65 @@
/****************************************************************************** /******************************************************************************
* Icinga 2 * * Icinga 2 *
* Copyright (C) 2012-2018 Icinga Development Team (https://www.icinga.com/) * * Copyright (C) 2012-2018 Icinga Development Team (https://www.icinga.com/) *
* * * *
* This program is free software; you can redistribute it and/or * * This program is free software; you can redistribute it and/or *
* modify it under the terms of the GNU General Public License * * modify it under the terms of the GNU General Public License *
* as published by the Free Software Foundation; either version 2 * * as published by the Free Software Foundation; either version 2 *
* of the License, or (at your option) any later version. * * of the License, or (at your option) any later version. *
* * * *
* This program is distributed in the hope that it will be useful, * * This program is distributed in the hope that it will be useful, *
* but WITHOUT ANY WARRANTY; without even the implied warranty of * * but WITHOUT ANY WARRANTY; without even the implied warranty of *
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
* GNU General Public License for more details. * * GNU General Public License for more details. *
* * * *
* You should have received a copy of the GNU General Public License * * You should have received a copy of the GNU General Public License *
* along with this program; if not, write to the Free Software Foundation * * along with this program; if not, write to the Free Software Foundation *
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA. * * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA. *
******************************************************************************/ ******************************************************************************/
#ifndef WIN32_LEAN_AND_MEAN #ifndef WIN32_LEAN_AND_MEAN
#define WIN32_LEAN_AND_MEAN //else winsock will be included with windows.h and conflict with winsock2 #define WIN32_LEAN_AND_MEAN //else winsock will be included with windows.h and conflict with winsock2
#endif #endif
#include "plugins/thresholds.hpp"
#include <boost/program_options.hpp>
#include <iostream>
#include <winsock2.h> #include <winsock2.h>
#include <iphlpapi.h> #include <iphlpapi.h>
#include <icmpapi.h> #include <icmpapi.h>
#include <Shlwapi.h> #include <shlwapi.h>
#include <ws2ipdef.h> #include <ws2ipdef.h>
#include <Mstcpip.h> #include <mstcpip.h>
#include <Ws2tcpip.h> #include <ws2tcpip.h>
#include <iostream>
#include "check_ping.h"
#define VERSION 1.0 #define VERSION 1.0
namespace po = boost::program_options; namespace po = boost::program_options;
static BOOL debug = FALSE; struct response
INT wmain(INT argc, WCHAR **argv)
{ {
po::variables_map vm; double avg;
printInfoStruct printInfo; unsigned int pMin = 0;
response response; unsigned int pMax = 0;
unsigned int dropped = 0;
};
WSADATA dat; struct printInfoStruct
{
threshold warn;
threshold crit;
threshold wpl;
threshold cpl;
std::wstring host;
std::wstring ip;
bool ipv6 = false;
int timeout = 1000;
int num = 5;
};
if (WSAStartup(MAKEWORD(2, 2), &dat)) { static bool l_Debug;
std::cout << "WSAStartup failed\n";
return 3;
}
if (parseArguments(argc, argv, vm, printInfo) != -1) static int parseArguments(int ac, WCHAR **av, po::variables_map& vm, printInfoStruct& printInfo)
return 3;
if (!resolveHostname(printInfo.host, printInfo.ipv6, printInfo.ip))
return 3;
if (printInfo.ipv6) {
if (check_ping6(printInfo, response) != -1)
return 3;
} else {
if (check_ping4(printInfo, response) != -1)
return 3;
}
WSACleanup();
return printOutput(printInfo, response);
}
INT parseArguments(INT ac, WCHAR **av, po::variables_map& vm, printInfoStruct& printInfo)
{ {
WCHAR namePath[MAX_PATH]; WCHAR namePath[MAX_PATH];
GetModuleFileName(NULL, namePath, MAX_PATH); GetModuleFileName(NULL, namePath, MAX_PATH);
@ -85,27 +74,27 @@ INT parseArguments(INT ac, WCHAR **av, po::variables_map& vm, printInfoStruct& p
("host,H", po::wvalue<std::wstring>()->required(), "Target hostname or IP. If an IPv6 address is given, the '-6' option must be set") ("host,H", po::wvalue<std::wstring>()->required(), "Target hostname or IP. If an IPv6 address is given, the '-6' option must be set")
(",4", "--Host is an IPv4 address or if it's a hostname: Resolve it to an IPv4 address (default)") (",4", "--Host is an IPv4 address or if it's a hostname: Resolve it to an IPv4 address (default)")
(",6", "--Host is an IPv6 address or if it's a hostname: Resolve it to an IPv6 address") (",6", "--Host is an IPv6 address or if it's a hostname: Resolve it to an IPv6 address")
("timeout,t", po::value<INT>(), "Specify timeout for requests in ms (default=1000)") ("timeout,t", po::value<int>(), "Specify timeout for requests in ms (default=1000)")
("packets,p", po::value<INT>(), "Declare ping count (default=5)") ("packets,p", po::value<int>(), "Declare ping count (default=5)")
("warning,w", po::wvalue<std::wstring>(), "Warning values: rtt,package loss") ("warning,w", po::wvalue<std::wstring>(), "Warning values: rtt,package loss")
("critical,c", po::wvalue<std::wstring>(), "Critical values: rtt,package loss") ("critical,c", po::wvalue<std::wstring>(), "Critical values: rtt,package loss")
; ;
po::basic_command_line_parser<WCHAR> parser(ac, av); po::wcommand_line_parser parser(ac, av);
try { try {
po::store( po::store(
parser parser
.options(desc) .options(desc)
.style( .style(
po::command_line_style::unix_style | po::command_line_style::unix_style |
po::command_line_style::allow_long_disguise & po::command_line_style::allow_long_disguise &
~po::command_line_style::allow_guessing ~po::command_line_style::allow_guessing
) )
.run(), .run(),
vm); vm);
vm.notify(); vm.notify();
} catch (std::exception& e) { } catch (const std::exception& e) {
std::cout << e.what() << '\n' << desc << '\n'; std::cout << e.what() << '\n' << desc << '\n';
return 3; return 3;
} }
@ -160,8 +149,8 @@ INT parseArguments(INT ac, WCHAR **av, po::variables_map& vm, printInfoStruct& p
std::cout << "Conflicting options \"4\" and \"6\"" << '\n'; std::cout << "Conflicting options \"4\" and \"6\"" << '\n';
return 3; return 3;
} }
if (vm.count("-6"))
printInfo.ipv6 = TRUE; printInfo.ipv6 = vm.count("-6") > 0;
if (vm.count("warning")) { if (vm.count("warning")) {
std::vector<std::wstring> sVec = splitMultiOptions(vm["warning"].as<std::wstring>()); std::vector<std::wstring> sVec = splitMultiOptions(vm["warning"].as<std::wstring>());
@ -176,11 +165,12 @@ INT parseArguments(INT ac, WCHAR **av, po::variables_map& vm, printInfoStruct& p
std::cout << "Packet loss must be percentage" << '\n'; std::cout << "Packet loss must be percentage" << '\n';
return 3; return 3;
} }
} catch (std::invalid_argument& e) { } catch (const std::invalid_argument& e) {
std::cout << e.what() << '\n'; std::cout << e.what() << '\n';
return 3; return 3;
} }
} }
if (vm.count("critical")) { if (vm.count("critical")) {
std::vector<std::wstring> sVec = splitMultiOptions(vm["critical"].as<std::wstring>()); std::vector<std::wstring> sVec = splitMultiOptions(vm["critical"].as<std::wstring>());
if (sVec.size() != 2) { if (sVec.size() != 2) {
@ -194,29 +184,28 @@ INT parseArguments(INT ac, WCHAR **av, po::variables_map& vm, printInfoStruct& p
std::cout << "Packet loss must be percentage" << '\n'; std::cout << "Packet loss must be percentage" << '\n';
return 3; return 3;
} }
} catch (std::invalid_argument& e) { } catch (const std::invalid_argument& e) {
std::cout << e.what() << '\n'; std::cout << e.what() << '\n';
return 3; return 3;
} }
} }
if (vm.count("timeout")) if (vm.count("timeout"))
printInfo.timeout = vm["timeout"].as<INT>(); printInfo.timeout = vm["timeout"].as<int>();
if (vm.count("packets"))
printInfo.num = vm["packets"].as<INT>();
if (vm.count("packets"))
printInfo.num = vm["packets"].as<int>();
printInfo.host = vm["host"].as<std::wstring>(); printInfo.host = vm["host"].as<std::wstring>();
if (vm.count("debug")) l_Debug = vm.count("debug") > 0;
debug = TRUE;
return -1; return -1;
} }
INT printOutput(printInfoStruct& printInfo, response& response) static int printOutput(printInfoStruct& printInfo, response& response)
{ {
if (debug) if (l_Debug)
std::wcout << L"Constructing output string" << '\n'; std::wcout << L"Constructing output string" << '\n';
state state = OK; state state = OK;
@ -239,37 +228,39 @@ INT printOutput(printInfoStruct& printInfo, response& response)
return 2; return 2;
} }
std::wcout << L"PING ";
switch (state) { switch (state) {
case OK: case OK:
std::wcout << L"PING OK RTA: " << response.avg << L"ms Packet loss: " << removeZero(plp) << "% | " << perf.str() << '\n'; std::wcout << L"OK";
break; break;
case WARNING: case WARNING:
std::wcout << L"PING WARNING RTA: " << response.avg << L"ms Packet loss: " << removeZero(plp) << "% | " << perf.str() << '\n'; std::wcout << L"WARNING";
break; break;
case CRITICAL: case CRITICAL:
std::wcout << L"PING CRITICAL RTA: " << response.avg << L"ms Packet loss: " << removeZero(plp) << "% | " << perf.str() << '\n'; std::wcout << L"CRITICAL";
break; break;
} }
std::wcout << L" RTA: " << response.avg << L"ms Packet loss: " << removeZero(plp) << "% | " << perf.str() << '\n';
return state; return state;
} }
BOOL resolveHostname(CONST std::wstring hostname, BOOL ipv6, std::wstring& ipaddr) static bool resolveHostname(const std::wstring& hostname, bool ipv6, std::wstring& ipaddr)
{ {
ADDRINFOW *result = NULL;
ADDRINFOW *ptr = NULL;
ADDRINFOW hints; ADDRINFOW hints;
ZeroMemory(&hints, sizeof(hints)); ZeroMemory(&hints, sizeof(hints));
wchar_t ipstringbuffer[46];
if (ipv6) if (ipv6)
hints.ai_family = AF_INET6; hints.ai_family = AF_INET6;
else else
hints.ai_family = AF_INET; hints.ai_family = AF_INET;
if (debug) if (l_Debug)
std::wcout << L"Resolving hostname \"" << hostname << L"\"\n"; std::wcout << L"Resolving hostname \"" << hostname << L"\"\n";
ADDRINFOW *result = NULL;
DWORD ret = GetAddrInfoW(hostname.c_str(), NULL, &hints, &result); DWORD ret = GetAddrInfoW(hostname.c_str(), NULL, &hints, &result);
if (ret) { if (ret) {
@ -277,35 +268,31 @@ BOOL resolveHostname(CONST std::wstring hostname, BOOL ipv6, std::wstring& ipadd
return false; return false;
} }
wchar_t ipstringbuffer[46];
if (ipv6) { if (ipv6) {
struct sockaddr_in6 *address6 = (struct sockaddr_in6 *) result->ai_addr; struct sockaddr_in6 *address6 = (struct sockaddr_in6 *)result->ai_addr;
InetNtop(AF_INET6, &address6->sin6_addr, ipstringbuffer, 46); InetNtop(AF_INET6, &address6->sin6_addr, ipstringbuffer, 46);
} else { }
struct sockaddr_in *address4 = (struct sockaddr_in *) result->ai_addr; else {
struct sockaddr_in *address4 = (struct sockaddr_in *)result->ai_addr;
InetNtop(AF_INET, &address4->sin_addr, ipstringbuffer, 46); InetNtop(AF_INET, &address4->sin_addr, ipstringbuffer, 46);
} }
if (debug) if (l_Debug)
std::wcout << L"Resolved to \"" << ipstringbuffer << L"\"\n"; std::wcout << L"Resolved to \"" << ipstringbuffer << L"\"\n";
ipaddr = ipstringbuffer; ipaddr = ipstringbuffer;
return true; return true;
} }
INT check_ping4(CONST printInfoStruct& pi, response& response) static int check_ping4(const printInfoStruct& pi, response& response)
{ {
in_addr ipDest4; if (l_Debug)
HANDLE hIcmp;
DWORD dwRet = 0, dwRepSize = 0;
LPVOID repBuf = NULL;
UINT rtt = 0;
INT num = pi.num;
LARGE_INTEGER frequency, timer1, timer2;
LPCWSTR term;
if (debug)
std::wcout << L"Parsing ip address" << '\n'; std::wcout << L"Parsing ip address" << '\n';
in_addr ipDest4;
LPCWSTR term;
if (RtlIpv4StringToAddress(pi.ip.c_str(), TRUE, &term, &ipDest4) == STATUS_INVALID_PARAMETER) { if (RtlIpv4StringToAddress(pi.ip.c_str(), TRUE, &term, &ipDest4) == STATUS_INVALID_PARAMETER) {
std::wcout << pi.ip << " is not a valid ip address\n"; std::wcout << pi.ip << " is not a valid ip address\n";
return 3; return 3;
@ -316,46 +303,53 @@ INT check_ping4(CONST printInfoStruct& pi, response& response)
return 3; return 3;
} }
if (debug) if (l_Debug)
std::wcout << L"Creating Icmp File\n"; std::wcout << L"Creating Icmp File\n";
HANDLE hIcmp;
if ((hIcmp = IcmpCreateFile()) == INVALID_HANDLE_VALUE) if ((hIcmp = IcmpCreateFile()) == INVALID_HANDLE_VALUE)
goto die; goto die;
dwRepSize = sizeof(ICMP_ECHO_REPLY) + 8; DWORD dwRepSize = sizeof(ICMP_ECHO_REPLY) + 8;
repBuf = reinterpret_cast<VOID *>(new BYTE[dwRepSize]); void *repBuf = reinterpret_cast<VOID *>(new BYTE[dwRepSize]);
if (repBuf == NULL) if (repBuf == NULL)
goto die; goto die;
unsigned int rtt = 0;
int num = pi.num;
LARGE_INTEGER frequency;
QueryPerformanceFrequency(&frequency); QueryPerformanceFrequency(&frequency);
do { do {
LARGE_INTEGER timer1;
QueryPerformanceCounter(&timer1); QueryPerformanceCounter(&timer1);
if (debug) if (l_Debug)
std::wcout << L"Sending Icmp echo\n"; std::wcout << L"Sending Icmp echo\n";
if (!IcmpSendEcho2(hIcmp, NULL, NULL, NULL, ipDest4.S_un.S_addr, if (!IcmpSendEcho2(hIcmp, NULL, NULL, NULL, ipDest4.S_un.S_addr,
NULL, 0, NULL, repBuf, dwRepSize, pi.timeout)) { NULL, 0, NULL, repBuf, dwRepSize, pi.timeout)) {
response.dropped++; response.dropped++;
if (debug) if (l_Debug)
std::wcout << L"Dropped: Response was 0" << '\n'; std::wcout << L"Dropped: Response was 0" << '\n';
continue; continue;
} }
if (debug) if (l_Debug)
std::wcout << "Ping recieved" << '\n'; std::wcout << "Ping recieved" << '\n';
PICMP_ECHO_REPLY pEchoReply = static_cast<PICMP_ECHO_REPLY>(repBuf); PICMP_ECHO_REPLY pEchoReply = static_cast<PICMP_ECHO_REPLY>(repBuf);
if (pEchoReply->Status != IP_SUCCESS) { if (pEchoReply->Status != IP_SUCCESS) {
response.dropped++; response.dropped++;
if (debug) if (l_Debug)
std::wcout << L"Dropped: echo reply status " << pEchoReply->Status << '\n'; std::wcout << L"Dropped: echo reply status " << pEchoReply->Status << '\n';
continue; continue;
} }
if (debug) if (l_Debug)
std::wcout << L"Recorded rtt of " << pEchoReply->RoundTripTime << '\n'; std::wcout << L"Recorded rtt of " << pEchoReply->RoundTripTime << '\n';
rtt += pEchoReply->RoundTripTime; rtt += pEchoReply->RoundTripTime;
@ -364,12 +358,14 @@ INT check_ping4(CONST printInfoStruct& pi, response& response)
else if (pEchoReply->RoundTripTime > response.pMax) else if (pEchoReply->RoundTripTime > response.pMax)
response.pMax = pEchoReply->RoundTripTime; response.pMax = pEchoReply->RoundTripTime;
LARGE_INTEGER timer2;
QueryPerformanceCounter(&timer2); QueryPerformanceCounter(&timer2);
if (((timer2.QuadPart - timer1.QuadPart) * 1000 / frequency.QuadPart) < pi.timeout) if (((timer2.QuadPart - timer1.QuadPart) * 1000 / frequency.QuadPart) < pi.timeout)
Sleep(pi.timeout - ((timer2.QuadPart - timer1.QuadPart) * 1000 / frequency.QuadPart)); Sleep(pi.timeout - ((timer2.QuadPart - timer1.QuadPart) * 1000 / frequency.QuadPart));
} while (--num); } while (--num);
if (debug) if (l_Debug)
std::wcout << L"All pings sent. Cleaning up and returning" << '\n'; std::wcout << L"All pings sent. Cleaning up and returning" << '\n';
if (hIcmp) if (hIcmp)
@ -382,7 +378,7 @@ INT check_ping4(CONST printInfoStruct& pi, response& response)
return -1; return -1;
die: die:
die(); printErrorInfo();
if (hIcmp) if (hIcmp)
IcmpCloseHandle(hIcmp); IcmpCloseHandle(hIcmp);
if (repBuf) if (repBuf)
@ -391,21 +387,18 @@ die:
return 3; return 3;
} }
INT check_ping6(CONST printInfoStruct& pi, response& response) static int check_ping6(const printInfoStruct& pi, response& response)
{ {
sockaddr_in6 ipDest6, ipSource6;
IP_OPTION_INFORMATION ipInfo = { 30, 0, 0, 0, NULL };
DWORD dwRepSize = sizeof(ICMPV6_ECHO_REPLY) + 8; DWORD dwRepSize = sizeof(ICMPV6_ECHO_REPLY) + 8;
LPVOID repBuf = reinterpret_cast<VOID *>(new BYTE[dwRepSize]); void *repBuf = reinterpret_cast<void *>(new BYTE[dwRepSize]);
HANDLE hIcmp = NULL;
LARGE_INTEGER frequency, timer1, timer2; int num = pi.num;
INT num = pi.num; unsigned int rtt = 0;
UINT rtt = 0;
if (debug) if (l_Debug)
std::wcout << L"Parsing ip address" << '\n'; std::wcout << L"Parsing ip address" << '\n';
sockaddr_in6 ipDest6;
if (RtlIpv6StringToAddressEx(pi.ip.c_str(), &ipDest6.sin6_addr, &ipDest6.sin6_scope_id, &ipDest6.sin6_port)) { if (RtlIpv6StringToAddressEx(pi.ip.c_str(), &ipDest6.sin6_addr, &ipDest6.sin6_scope_id, &ipDest6.sin6_port)) {
std::wcout << pi.ip << " is not a valid ipv6 address" << '\n'; std::wcout << pi.ip << " is not a valid ipv6 address" << '\n';
return 3; return 3;
@ -413,35 +406,41 @@ INT check_ping6(CONST printInfoStruct& pi, response& response)
ipDest6.sin6_family = AF_INET6; ipDest6.sin6_family = AF_INET6;
sockaddr_in6 ipSource6;
ipSource6.sin6_addr = in6addr_any; ipSource6.sin6_addr = in6addr_any;
ipSource6.sin6_family = AF_INET6; ipSource6.sin6_family = AF_INET6;
ipSource6.sin6_flowinfo = 0; ipSource6.sin6_flowinfo = 0;
ipSource6.sin6_port = 0; ipSource6.sin6_port = 0;
if (debug) if (l_Debug)
std::wcout << L"Creating Icmp File" << '\n'; std::wcout << L"Creating Icmp File" << '\n';
hIcmp = Icmp6CreateFile(); HANDLE hIcmp = Icmp6CreateFile();
if (hIcmp == INVALID_HANDLE_VALUE) { if (hIcmp == INVALID_HANDLE_VALUE) {
goto die; goto die;
} }
IP_OPTION_INFORMATION ipInfo = { 30, 0, 0, 0, NULL };
LARGE_INTEGER frequency;
QueryPerformanceFrequency(&frequency); QueryPerformanceFrequency(&frequency);
do { do {
LARGE_INTEGER timer1;
QueryPerformanceCounter(&timer1); QueryPerformanceCounter(&timer1);
if (debug) if (l_Debug)
std::wcout << L"Sending Icmp echo" << '\n'; std::wcout << L"Sending Icmp echo" << '\n';
if (!Icmp6SendEcho2(hIcmp, NULL, NULL, NULL, &ipSource6, &ipDest6, if (!Icmp6SendEcho2(hIcmp, NULL, NULL, NULL, &ipSource6, &ipDest6,
NULL, 0, &ipInfo, repBuf, dwRepSize, pi.timeout)) { NULL, 0, &ipInfo, repBuf, dwRepSize, pi.timeout)) {
response.dropped++; response.dropped++;
if (debug) if (l_Debug)
std::wcout << L"Dropped: Response was 0" << '\n'; std::wcout << L"Dropped: Response was 0" << '\n';
continue; continue;
} }
if (debug) if (l_Debug)
std::wcout << "Ping recieved" << '\n'; std::wcout << "Ping recieved" << '\n';
Icmp6ParseReplies(repBuf, dwRepSize); Icmp6ParseReplies(repBuf, dwRepSize);
@ -450,14 +449,14 @@ INT check_ping6(CONST printInfoStruct& pi, response& response)
if (pEchoReply->Status != IP_SUCCESS) { if (pEchoReply->Status != IP_SUCCESS) {
response.dropped++; response.dropped++;
if (debug) if (l_Debug)
std::wcout << L"Dropped: echo reply status " << pEchoReply->Status << '\n'; std::wcout << L"Dropped: echo reply status " << pEchoReply->Status << '\n';
continue; continue;
} }
rtt += pEchoReply->RoundTripTime; rtt += pEchoReply->RoundTripTime;
if (debug) if (l_Debug)
std::wcout << L"Recorded rtt of " << pEchoReply->RoundTripTime << '\n'; std::wcout << L"Recorded rtt of " << pEchoReply->RoundTripTime << '\n';
if (response.pMin == 0 || pEchoReply->RoundTripTime < response.pMin) if (response.pMin == 0 || pEchoReply->RoundTripTime < response.pMin)
@ -465,28 +464,64 @@ INT check_ping6(CONST printInfoStruct& pi, response& response)
else if (pEchoReply->RoundTripTime > response.pMax) else if (pEchoReply->RoundTripTime > response.pMax)
response.pMax = pEchoReply->RoundTripTime; response.pMax = pEchoReply->RoundTripTime;
LARGE_INTEGER timer2;
QueryPerformanceCounter(&timer2); QueryPerformanceCounter(&timer2);
if (((timer2.QuadPart - timer1.QuadPart) * 1000 / frequency.QuadPart) < pi.timeout) if (((timer2.QuadPart - timer1.QuadPart) * 1000 / frequency.QuadPart) < pi.timeout)
Sleep(pi.timeout - ((timer2.QuadPart - timer1.QuadPart) * 1000 / frequency.QuadPart)); Sleep(pi.timeout - ((timer2.QuadPart - timer1.QuadPart) * 1000 / frequency.QuadPart));
} while (--num); } while (--num);
if (debug) if (l_Debug)
std::wcout << L"All pings sent. Cleaning up and returning" << '\n'; std::wcout << L"All pings sent. Cleaning up and returning" << '\n';
if (hIcmp) if (hIcmp)
IcmpCloseHandle(hIcmp); IcmpCloseHandle(hIcmp);
if (repBuf) if (repBuf)
delete reinterpret_cast<VOID *>(repBuf); delete reinterpret_cast<BYTE *>(repBuf);
response.avg = ((double)rtt / pi.num); response.avg = ((double)rtt / pi.num);
return -1; return -1;
die: die:
die(GetLastError()); printErrorInfo(GetLastError());
if (hIcmp) if (hIcmp)
IcmpCloseHandle(hIcmp); IcmpCloseHandle(hIcmp);
if (repBuf) if (repBuf)
delete reinterpret_cast<VOID *>(repBuf); delete reinterpret_cast<BYTE *>(repBuf);
return 3; return 3;
} }
int wmain(int argc, WCHAR **argv)
{
WSADATA dat;
if (WSAStartup(MAKEWORD(2, 2), &dat)) {
std::cout << "WSAStartup failed\n";
return 3;
}
po::variables_map vm;
printInfoStruct printInfo;
if (parseArguments(argc, argv, vm, printInfo) != -1)
return 3;
if (!resolveHostname(printInfo.host, printInfo.ipv6, printInfo.ip))
return 3;
response response;
if (printInfo.ipv6) {
if (check_ping6(printInfo, response) != -1)
return 3;
} else {
if (check_ping4(printInfo, response) != -1)
return 3;
}
WSACleanup();
return printOutput(printInfo, response);
}

View File

@ -1,47 +0,0 @@
/******************************************************************************
* Icinga 2 *
* Copyright (C) 2012-2018 Icinga Development Team (https://www.icinga.com/) *
* *
* This program is free software; you can redistribute it and/or *
* modify it under the terms of the GNU General Public License *
* as published by the Free Software Foundation; either version 2 *
* of the License, or (at your option) any later version. *
* *
* This program is distributed in the hope that it will be useful, *
* but WITHOUT ANY WARRANTY; without even the implied warranty of *
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
* GNU General Public License for more details. *
* *
* You should have received a copy of the GNU General Public License *
* along with this program; if not, write to the Free Software Foundation *
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA. *
******************************************************************************/
#ifndef CHECK_PING_H
#define CHECK_PING_H
#include "thresholds.h"
#include "boost/program_options.hpp"
struct response
{
DOUBLE avg;
UINT pMin = 0, pMax = 0, dropped = 0;
};
struct printInfoStruct
{
threshold warn, crit;
threshold wpl, cpl;
std::wstring host, ip;
BOOL ipv6 = FALSE;
DWORD timeout = 1000;
INT num = 5;
};
INT printOutput(printInfoStruct&, response&);
INT parseArguments(INT, WCHAR **, boost::program_options::variables_map&, printInfoStruct&);
INT check_ping4(CONST printInfoStruct&, response&);
INT check_ping6(CONST printInfoStruct&, response&);
BOOL resolveHostname(CONST std::wstring, BOOL, std::wstring&);
#endif // !CHECK_PING_H

View File

@ -16,36 +16,28 @@
* along with this program; if not, write to the Free Software Foundation * * along with this program; if not, write to the Free Software Foundation *
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA. * * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA. *
******************************************************************************/ ******************************************************************************/
#include <Windows.h>
#include <Shlwapi.h>
#include <tlhelp32.h>
#include <iostream>
#include "check_procs.h" #include "plugins/thresholds.hpp"
#include <boost/program_options.hpp>
#include <iostream>
#include <windows.h>
#include <shlwapi.h>
#include <tlhelp32.h>
#define VERSION 1.0 #define VERSION 1.0
namespace po = boost::program_options; namespace po = boost::program_options;
static BOOL debug = FALSE; struct printInfoStruct
INT wmain(INT argc, WCHAR **argv)
{ {
po::variables_map vm; threshold warn;
printInfoStruct printInfo = { }; threshold crit;
std::wstring user;
};
INT r = parseArguments(argc, argv, vm, printInfo); static bool l_Debug;
if (r != -1) static int parseArguments(int ac, WCHAR **av, po::variables_map& vm, printInfoStruct& printInfo)
return r;
if(!printInfo.user.empty())
return printOutput(countProcs(printInfo.user), printInfo);
return printOutput(countProcs(), printInfo);
}
INT parseArguments(INT ac, WCHAR **av, po::variables_map& vm, printInfoStruct& printInfo)
{ {
WCHAR namePath[MAX_PATH]; WCHAR namePath[MAX_PATH];
GetModuleFileName(NULL, namePath, MAX_PATH); GetModuleFileName(NULL, namePath, MAX_PATH);
@ -62,19 +54,19 @@ INT parseArguments(INT ac, WCHAR **av, po::variables_map& vm, printInfoStruct& p
("critical,c", po::wvalue<std::wstring>(), "Critical threshold") ("critical,c", po::wvalue<std::wstring>(), "Critical threshold")
; ;
po::basic_command_line_parser<WCHAR> parser(ac, av); po::wcommand_line_parser parser(ac, av);
try { try {
po::store( po::store(
parser parser
.options(desc) .options(desc)
.style( .style(
po::command_line_style::unix_style | po::command_line_style::unix_style |
po::command_line_style::allow_long_disguise) po::command_line_style::allow_long_disguise)
.run(), .run(),
vm); vm);
vm.notify(); vm.notify();
} catch (std::exception& e) { } catch (const std::exception& e) {
std::cout << e.what() << '\n' << desc << '\n'; std::cout << e.what() << '\n' << desc << '\n';
return 3; return 3;
} }
@ -129,7 +121,7 @@ INT parseArguments(INT ac, WCHAR **av, po::variables_map& vm, printInfoStruct& p
if (vm.count("warning")) { if (vm.count("warning")) {
try { try {
printInfo.warn = threshold(vm["warning"].as<std::wstring>()); printInfo.warn = threshold(vm["warning"].as<std::wstring>());
} catch (std::invalid_argument& e) { } catch (const std::invalid_argument& e) {
std::cout << e.what() << '\n'; std::cout << e.what() << '\n';
return 3; return 3;
} }
@ -137,7 +129,7 @@ INT parseArguments(INT ac, WCHAR **av, po::variables_map& vm, printInfoStruct& p
if (vm.count("critical")) { if (vm.count("critical")) {
try { try {
printInfo.crit = threshold(vm["critical"].as<std::wstring>()); printInfo.crit = threshold(vm["critical"].as<std::wstring>());
} catch (std::invalid_argument& e) { } catch (const std::invalid_argument& e) {
std::cout << e.what() << '\n'; std::cout << e.what() << '\n';
return 3; return 3;
} }
@ -146,15 +138,14 @@ INT parseArguments(INT ac, WCHAR **av, po::variables_map& vm, printInfoStruct& p
if (vm.count("user")) if (vm.count("user"))
printInfo.user = vm["user"].as<std::wstring>(); printInfo.user = vm["user"].as<std::wstring>();
if (vm.count("debug")) l_Debug = vm.count("debug") > 0;
debug = TRUE;
return -1; return -1;
} }
INT printOutput(CONST INT numProcs, printInfoStruct& printInfo) static int printOutput(const int numProcs, printInfoStruct& printInfo)
{ {
if (debug) if (l_Debug)
std::wcout << L"Constructing output string" << '\n'; std::wcout << L"Constructing output string" << '\n';
state state = OK; state state = OK;
@ -165,46 +156,46 @@ INT printOutput(CONST INT numProcs, printInfoStruct& printInfo)
if (printInfo.crit.rend(numProcs)) if (printInfo.crit.rend(numProcs))
state = CRITICAL; state = CRITICAL;
std::wstring user = L""; std::wstring user;
if (!printInfo.user.empty()) if (!printInfo.user.empty())
user.append(L" processes of user ").append(printInfo.user); user = L" processes of user " + printInfo.user;
std::wcout << L"PROCS ";
switch (state) { switch (state) {
case OK: case OK:
std::wcout << L"PROCS OK " << numProcs << user << L" | procs=" << numProcs << L";" std::wcout << L"OK";
<< printInfo.warn.pString() << L";" << printInfo.crit.pString() << L";0;" << '\n';
break; break;
case WARNING: case WARNING:
std::wcout << L"PROCS WARNING " << numProcs << user << L" | procs=" << numProcs << L";" std::wcout << L"WARNING";
<< printInfo.warn.pString() << L";" << printInfo.crit.pString() << L";0;" << '\n';
break; break;
case CRITICAL: case CRITICAL:
std::wcout << L"PROCS CRITICAL " << numProcs << user << L" | procs=" << numProcs << L";" std::wcout << L"CRITICAL";
<< printInfo.warn.pString() << L";" << printInfo.crit.pString() << L";0;" << '\n';
break; break;
} }
std::wcout << L" " << numProcs << user << L" | procs=" << numProcs << L";"
<< printInfo.warn.pString() << L";" << printInfo.crit.pString() << L";0;" << '\n';
return state; return state;
} }
INT countProcs() static int countProcs()
{ {
if (debug) if (l_Debug)
std::wcout << L"Counting all processes" << '\n'; std::wcout << L"Counting all processes" << '\n';
HANDLE hProcessSnap = NULL; if (l_Debug)
PROCESSENTRY32 pe32;
if (debug)
std::wcout << L"Creating snapshot" << '\n'; std::wcout << L"Creating snapshot" << '\n';
hProcessSnap = CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, 0); HANDLE hProcessSnap = CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, 0);
if (hProcessSnap == INVALID_HANDLE_VALUE) if (hProcessSnap == INVALID_HANDLE_VALUE)
return -1; return -1;
PROCESSENTRY32 pe32;
pe32.dwSize = sizeof(PROCESSENTRY32); pe32.dwSize = sizeof(PROCESSENTRY32);
if (debug) if (l_Debug)
std::wcout << L"Grabbing first proccess" << '\n'; std::wcout << L"Grabbing first proccess" << '\n';
if (!Process32First(hProcessSnap, &pe32)) { if (!Process32First(hProcessSnap, &pe32)) {
@ -212,30 +203,30 @@ INT countProcs()
return -1; return -1;
} }
INT numProcs = 0; if (l_Debug)
if (debug)
std::wcout << L"Counting processes..." << '\n'; std::wcout << L"Counting processes..." << '\n';
int numProcs = 0;
do { do {
++numProcs; ++numProcs;
} while (Process32Next(hProcessSnap, &pe32)); } while (Process32Next(hProcessSnap, &pe32));
if (debug) if (l_Debug)
std::wcout << L"Found " << numProcs << L" processes. Cleaning up udn returning" << '\n'; std::wcout << L"Found " << numProcs << L" processes. Cleaning up udn returning" << '\n';
if (hProcessSnap) CloseHandle(hProcessSnap);
CloseHandle(hProcessSnap);
return numProcs; return numProcs;
} }
INT countProcs(CONST std::wstring user) static int countProcs(const std::wstring& user)
{ {
if (debug) if (l_Debug)
std::wcout << L"Counting all processes of user" << user << '\n'; std::wcout << L"Counting all processes of user" << user << '\n';
CONST WCHAR *wuser = user.c_str(); const WCHAR *wuser = user.c_str();
INT numProcs = 0; int numProcs = 0;
HANDLE hProcessSnap, hProcess = NULL, hToken = NULL; HANDLE hProcessSnap, hProcess = NULL, hToken = NULL;
PROCESSENTRY32 pe32; PROCESSENTRY32 pe32;
@ -244,7 +235,7 @@ INT countProcs(CONST std::wstring user)
SID_NAME_USE sidNameUse; SID_NAME_USE sidNameUse;
LPWSTR AcctName, DomainName; LPWSTR AcctName, DomainName;
if (debug) if (l_Debug)
std::wcout << L"Creating snapshot" << '\n'; std::wcout << L"Creating snapshot" << '\n';
hProcessSnap = CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, 0); hProcessSnap = CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, 0);
@ -253,17 +244,17 @@ INT countProcs(CONST std::wstring user)
pe32.dwSize = sizeof(PROCESSENTRY32); pe32.dwSize = sizeof(PROCESSENTRY32);
if (debug) if (l_Debug)
std::wcout << L"Grabbing first proccess" << '\n'; std::wcout << L"Grabbing first proccess" << '\n';
if (!Process32First(hProcessSnap, &pe32)) if (!Process32First(hProcessSnap, &pe32))
goto die; goto die;
if (debug) if (l_Debug)
std::wcout << L"Counting processes..." << '\n'; std::wcout << L"Counting processes..." << '\n';
do { do {
if (debug) if (l_Debug)
std::wcout << L"Getting process token" << '\n'; std::wcout << L"Getting process token" << '\n';
//get ProcessToken //get ProcessToken
@ -281,7 +272,7 @@ INT countProcs(CONST std::wstring user)
pSIDTokenUser = reinterpret_cast<PTOKEN_USER>(new BYTE[dwReturnLength]); pSIDTokenUser = reinterpret_cast<PTOKEN_USER>(new BYTE[dwReturnLength]);
memset(pSIDTokenUser, 0, dwReturnLength); memset(pSIDTokenUser, 0, dwReturnLength);
if (debug) if (l_Debug)
std::wcout << L"Received token, saving information" << '\n'; std::wcout << L"Received token, saving information" << '\n';
//write Info in pSIDTokenUser //write Info in pSIDTokenUser
@ -293,7 +284,7 @@ INT countProcs(CONST std::wstring user)
dwAcctName = 1; dwAcctName = 1;
dwDomainName = 1; dwDomainName = 1;
if (debug) if (l_Debug)
std::wcout << L"Looking up SID" << '\n'; std::wcout << L"Looking up SID" << '\n';
//get dwAcctName and dwDomainName size //get dwAcctName and dwDomainName size
@ -309,11 +300,11 @@ INT countProcs(CONST std::wstring user)
(LPDWORD)&dwAcctName, DomainName, (LPDWORD)&dwDomainName, &sidNameUse)) (LPDWORD)&dwAcctName, DomainName, (LPDWORD)&dwDomainName, &sidNameUse))
continue; continue;
if (debug) if (l_Debug)
std::wcout << L"Comparing " << AcctName << L" to " << wuser << '\n'; std::wcout << L"Comparing " << AcctName << L" to " << wuser << '\n';
if (!wcscmp(AcctName, wuser)) { if (!wcscmp(AcctName, wuser)) {
++numProcs; ++numProcs;
if (debug) if (l_Debug)
std::wcout << L"Is process of " << wuser << L" (" << numProcs << L")" << '\n'; std::wcout << L"Is process of " << wuser << L" (" << numProcs << L")" << '\n';
} }
@ -333,3 +324,19 @@ die:
delete[] reinterpret_cast<PTOKEN_USER>(pSIDTokenUser); delete[] reinterpret_cast<PTOKEN_USER>(pSIDTokenUser);
return numProcs; return numProcs;
} }
int wmain(int argc, WCHAR **argv)
{
po::variables_map vm;
printInfoStruct printInfo = { };
int r = parseArguments(argc, argv, vm, printInfo);
if (r != -1)
return r;
if (!printInfo.user.empty())
return printOutput(countProcs(printInfo.user), printInfo);
return printOutput(countProcs(), printInfo);
}

View File

@ -1,36 +0,0 @@
/******************************************************************************
* Icinga 2 *
* Copyright (C) 2012-2018 Icinga Development Team (https://www.icinga.com/) *
* *
* This program is free software; you can redistribute it and/or *
* modify it under the terms of the GNU General Public License *
* as published by the Free Software Foundation; either version 2 *
* of the License, or (at your option) any later version. *
* *
* This program is distributed in the hope that it will be useful, *
* but WITHOUT ANY WARRANTY; without even the implied warranty of *
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
* GNU General Public License for more details. *
* *
* You should have received a copy of the GNU General Public License *
* along with this program; if not, write to the Free Software Foundation *
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA. *
******************************************************************************/
#ifndef CHECK_PROCS_H
#define CHECK_PROCS_H
#include "thresholds.h"
#include "boost/program_options.hpp"
struct printInfoStruct
{
threshold warn, crit;
std::wstring user;
};
INT countProcs();
INT countProcs(CONST std::wstring);
INT parseArguments(INT, WCHAR **, boost::program_options::variables_map&, printInfoStruct&);
INT printOutput(CONST INT, printInfoStruct&);
#endif // !CHECK_PROCS_H

View File

@ -16,44 +16,27 @@
* along with this program; if not, write to the Free Software Foundation * * along with this program; if not, write to the Free Software Foundation *
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA. * * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA. *
******************************************************************************/ ******************************************************************************/
#include <Windows.h>
#include <Shlwapi.h> #include "plugins/thresholds.hpp"
#include <boost/program_options.hpp>
#include <iostream> #include <iostream>
#include <windows.h>
#include "check_service.h" #include <shlwapi.h>
#define VERSION 1.1 #define VERSION 1.1
namespace po = boost::program_options; namespace po = boost::program_options;
static BOOL debug; struct printInfoStruct
INT wmain(INT argc, WCHAR **argv)
{ {
po::variables_map vm; bool warn;
printInfoStruct printInfo; DWORD ServiceState;
std::wstring service;
};
INT ret = parseArguments(argc, argv, vm, printInfo); static bool l_Debug;
if (ret != -1)
return ret;
if (vm.count("description")) static int parseArguments(int ac, WCHAR **av, po::variables_map& vm, printInfoStruct& printInfo)
printInfo.service = GetServiceByDescription(vm["service"].as<std::wstring>());
if (printInfo.service.empty()) {
std::wcout << "Could not find service matching description\n";
return 3;
}
printInfo.ServiceState = ServiceStatus(printInfo);
if (printInfo.ServiceState == -1)
return 3;
return printOutput(printInfo);
}
INT parseArguments(INT ac, WCHAR **av, po::variables_map& vm, printInfoStruct& printInfo)
{ {
WCHAR namePath[MAX_PATH]; WCHAR namePath[MAX_PATH];
GetModuleFileName(NULL, namePath, MAX_PATH); GetModuleFileName(NULL, namePath, MAX_PATH);
@ -64,13 +47,13 @@ INT parseArguments(INT ac, WCHAR **av, po::variables_map& vm, printInfoStruct& p
desc.add_options() desc.add_options()
("help,h", "Print help message and exit") ("help,h", "Print help message and exit")
("version,V", "Print version and exit") ("version,V", "Print version and exit")
("D", "Verbose/Debug output") ("debug,D", "Verbose/Debug output")
("service,s", po::wvalue<std::wstring>(), "Service name to check") ("service,s", po::wvalue<std::wstring>(), "Service name to check")
("description,d", "Use \"service\" to match on description") ("description,d", "Use \"service\" to match on description")
("warn,w", "Return warning (1) instead of critical (2),\n when service is not running") ("warn,w", "Return warning (1) instead of critical (2),\n when service is not running")
; ;
po::basic_command_line_parser<WCHAR> parser(ac, av); po::wcommand_line_parser parser(ac, av);
try { try {
po::store( po::store(
@ -82,8 +65,7 @@ INT parseArguments(INT ac, WCHAR **av, po::variables_map& vm, printInfoStruct& p
.run(), .run(),
vm); vm);
vm.notify(); vm.notify();
} } catch (const std::exception& e) {
catch (std::exception& e) {
std::cout << e.what() << '\n' << desc << '\n'; std::cout << e.what() << '\n' << desc << '\n';
return 3; return 3;
} }
@ -128,15 +110,14 @@ INT parseArguments(INT ac, WCHAR **av, po::variables_map& vm, printInfoStruct& p
printInfo.warn = vm.count("warn"); printInfo.warn = vm.count("warn");
if (vm.count("D")) l_Debug = vm.count("debug") > 0;
debug = TRUE;
return -1; return -1;
} }
INT printOutput(CONST printInfoStruct& printInfo) static int printOutput(const printInfoStruct& printInfo)
{ {
if (debug) if (l_Debug)
std::wcout << L"Constructing output string" << '\n'; std::wcout << L"Constructing output string" << '\n';
std::wstring perf; std::wstring perf;
@ -165,22 +146,24 @@ INT printOutput(CONST printInfoStruct& printInfo)
return state; return state;
} }
std::wstring GetServiceByDescription(CONST std::wstring& description) { static std::wstring getServiceByDescription(const std::wstring& description)
{
SC_HANDLE hSCM = NULL; SC_HANDLE hSCM = NULL;
LPENUM_SERVICE_STATUSW lpServices = NULL;
LPBYTE lpBuf = NULL; LPBYTE lpBuf = NULL;
DWORD cbBufSize = 0; DWORD cbBufSize = 0;
DWORD lpServicesReturned = 0; DWORD lpServicesReturned = 0;
DWORD pcbBytesNeeded = 0; DWORD pcbBytesNeeded = 0;
DWORD lpResumeHandle = 0;; DWORD lpResumeHandle = 0;;
if (debug) if (l_Debug)
std::wcout << L"Opening SC Manager" << '\n'; std::wcout << L"Opening SC Manager" << '\n';
hSCM = OpenSCManager(NULL, NULL, GENERIC_READ); hSCM = OpenSCManager(NULL, NULL, GENERIC_READ);
if (hSCM == NULL) if (hSCM == NULL)
goto die; goto die;
if (debug) if (l_Debug)
std::wcout << L"Determining initially required memory" << '\n'; std::wcout << L"Determining initially required memory" << '\n';
EnumServicesStatus(hSCM, SERVICE_WIN32 | SERVICE_DRIVER, SERVICE_STATE_ALL, NULL, 0, EnumServicesStatus(hSCM, SERVICE_WIN32 | SERVICE_DRIVER, SERVICE_STATE_ALL, NULL, 0,
@ -193,9 +176,9 @@ std::wstring GetServiceByDescription(CONST std::wstring& description) {
if (GetLastError() != ERROR_INSUFFICIENT_BUFFER && GetLastError() != ERROR_MORE_DATA) if (GetLastError() != ERROR_INSUFFICIENT_BUFFER && GetLastError() != ERROR_MORE_DATA)
goto die; goto die;
LPENUM_SERVICE_STATUSW lpServices = reinterpret_cast<LPENUM_SERVICE_STATUSW>(new BYTE[pcbBytesNeeded]); lpServices = reinterpret_cast<LPENUM_SERVICE_STATUSW>(new BYTE[pcbBytesNeeded]);
if (debug) if (l_Debug)
std::wcout << L"Requesting Service Information. Entry point: " << lpResumeHandle << '\n'; std::wcout << L"Requesting Service Information. Entry point: " << lpResumeHandle << '\n';
EnumServicesStatus(hSCM, SERVICE_WIN32 | SERVICE_DRIVER, SERVICE_STATE_ALL, lpServices, pcbBytesNeeded, EnumServicesStatus(hSCM, SERVICE_WIN32 | SERVICE_DRIVER, SERVICE_STATE_ALL, lpServices, pcbBytesNeeded,
@ -204,16 +187,16 @@ std::wstring GetServiceByDescription(CONST std::wstring& description) {
for (int index = 0; index < lpServicesReturned; index++) { for (int index = 0; index < lpServicesReturned; index++) {
LPWSTR lpCurrent = lpServices[index].lpServiceName; LPWSTR lpCurrent = lpServices[index].lpServiceName;
if (debug) { if (l_Debug) {
std::wcout << L"Opening Service \"" << lpServices[index].lpServiceName << L"\"\n"; std::wcout << L"Opening Service \"" << lpServices[index].lpServiceName << L"\"\n";
} }
SC_HANDLE hService = OpenService(hSCM, lpCurrent, SERVICE_QUERY_CONFIG); SC_HANDLE hService = OpenService(hSCM, lpCurrent, SERVICE_QUERY_CONFIG);
if (hService == NULL) if (!hService)
goto die; goto die;
DWORD dwBytesNeeded = 0; DWORD dwBytesNeeded = 0;
if (debug) if (l_Debug)
std::wcout << "Accessing config\n"; std::wcout << "Accessing config\n";
if (!QueryServiceConfig2(hService, SERVICE_CONFIG_DESCRIPTION, NULL, 0, &dwBytesNeeded) && GetLastError() != ERROR_INSUFFICIENT_BUFFER) if (!QueryServiceConfig2(hService, SERVICE_CONFIG_DESCRIPTION, NULL, 0, &dwBytesNeeded) && GetLastError() != ERROR_INSUFFICIENT_BUFFER)
@ -226,13 +209,13 @@ std::wstring GetServiceByDescription(CONST std::wstring& description) {
if (lpsd->lpDescription != NULL && lstrcmp(lpsd->lpDescription, L"") != 0) { if (lpsd->lpDescription != NULL && lstrcmp(lpsd->lpDescription, L"") != 0) {
std::wstring desc(lpsd->lpDescription); std::wstring desc(lpsd->lpDescription);
if (debug) if (l_Debug)
std::wcout << "Got description:\n" << desc << '\n'; std::wcout << "Got description:\n" << desc << '\n';
size_t p = desc.find(description); size_t p = desc.find(description);
if (desc.find(description) != desc.npos) if (desc.find(description) != desc.npos)
return lpCurrent; return lpCurrent;
} }
else if (debug) else if (l_Debug)
std::wcout << "No description found\n"; std::wcout << "No description found\n";
} }
@ -241,7 +224,7 @@ std::wstring GetServiceByDescription(CONST std::wstring& description) {
return L""; return L"";
die: die:
die(); printErrorInfo();
if (hSCM) if (hSCM)
CloseServiceHandle(hSCM); CloseServiceHandle(hSCM);
if (lpServices) if (lpServices)
@ -249,7 +232,7 @@ die:
return L""; return L"";
} }
DWORD ServiceStatus(CONST printInfoStruct& printInfo) static DWORD getServiceStatus(const printInfoStruct& printInfo)
{ {
SC_HANDLE hSCM; SC_HANDLE hSCM;
SC_HANDLE hService; SC_HANDLE hService;
@ -257,7 +240,7 @@ DWORD ServiceStatus(CONST printInfoStruct& printInfo)
DWORD lpResumeHandle = 0; DWORD lpResumeHandle = 0;
LPBYTE lpBuf = NULL; LPBYTE lpBuf = NULL;
if (debug) if (l_Debug)
std::wcout << L"Opening SC Manager" << '\n'; std::wcout << L"Opening SC Manager" << '\n';
hSCM = OpenSCManager(NULL, NULL, GENERIC_READ); hSCM = OpenSCManager(NULL, NULL, GENERIC_READ);
@ -279,7 +262,7 @@ DWORD ServiceStatus(CONST printInfoStruct& printInfo)
} }
die: die:
die(); printErrorInfo();
if (hSCM) if (hSCM)
CloseServiceHandle(hSCM); CloseServiceHandle(hSCM);
if (hService) if (hService)
@ -289,3 +272,28 @@ die:
return -1; return -1;
} }
int wmain(int argc, WCHAR **argv)
{
po::variables_map vm;
printInfoStruct printInfo;
int ret = parseArguments(argc, argv, vm, printInfo);
if (ret != -1)
return ret;
if (vm.count("description"))
printInfo.service = getServiceByDescription(vm["service"].as<std::wstring>());
if (printInfo.service.empty()) {
std::wcout << "Could not find service matching description\n";
return 3;
}
printInfo.ServiceState = getServiceStatus(printInfo);
if (printInfo.ServiceState == -1)
return 3;
return printOutput(printInfo);
}

View File

@ -1,37 +0,0 @@
/******************************************************************************
* Icinga 2 *
* Copyright (C) 2012-2018 Icinga Development Team (https://www.icinga.com/) *
* *
* This program is free software; you can redistribute it and/or *
* modify it under the terms of the GNU General Public License *
* as published by the Free Software Foundation; either version 2 *
* of the License, or (at your option) any later version. *
* *
* This program is distributed in the hope that it will be useful, *
* but WITHOUT ANY WARRANTY; without even the implied warranty of *
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
* GNU General Public License for more details. *
* *
* You should have received a copy of the GNU General Public License *
* along with this program; if not, write to the Free Software Foundation *
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA. *
******************************************************************************/
#ifndef CHECK_SERVICE_H
#define CHECK_SERVICE_H
#include "thresholds.h"
#include "boost/program_options.hpp"
struct printInfoStruct
{
BOOL warn;
DWORD ServiceState;
std::wstring service;
};
INT parseArguments(INT, WCHAR **, boost::program_options::variables_map&, printInfoStruct&);
INT printOutput(CONST printInfoStruct&);
std::wstring GetServiceByDescription(CONST std::wstring&);
DWORD ServiceStatus(CONST printInfoStruct&);
#endif // !CHECK_SERVICE_H

View File

@ -16,35 +16,30 @@
* along with this program; if not, write to the Free Software Foundation * * along with this program; if not, write to the Free Software Foundation *
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA. * * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA. *
******************************************************************************/ ******************************************************************************/
#include <Shlwapi.h>
#include <iostream>
#include <WinBase.h>
#include "check_swap.h" #include "plugins/thresholds.hpp"
#include <boost/program_options.hpp>
#include <iostream>
#include <shlwapi.h>
#include <winbase.h>
#define VERSION 1.0 #define VERSION 1.0
namespace po = boost::program_options; namespace po = boost::program_options;
static BOOL debug = FALSE; struct printInfoStruct
INT wmain(INT argc, WCHAR **argv)
{ {
printInfoStruct printInfo = { }; threshold warn;
po::variables_map vm; threshold crit;
double tSwap;
double aSwap;
double percentFree;
Bunit unit = BunitMB;
};
INT ret = parseArguments(argc, argv, vm, printInfo); static bool l_Debug;
if (ret != -1)
return ret;
ret = check_swap(printInfo); static int parseArguments(int ac, WCHAR **av, po::variables_map& vm, printInfoStruct& printInfo)
if (ret != -1)
return ret;
return printOutput(printInfo);
}
INT parseArguments(INT ac, WCHAR **av, po::variables_map& vm, printInfoStruct& printInfo)
{ {
WCHAR namePath[MAX_PATH]; WCHAR namePath[MAX_PATH];
GetModuleFileName(NULL, namePath, MAX_PATH); GetModuleFileName(NULL, namePath, MAX_PATH);
@ -61,19 +56,19 @@ INT parseArguments(INT ac, WCHAR **av, po::variables_map& vm, printInfoStruct& p
("unit,u", po::wvalue<std::wstring>(), "The unit to use for display (default MB)") ("unit,u", po::wvalue<std::wstring>(), "The unit to use for display (default MB)")
; ;
po::basic_command_line_parser<WCHAR> parser(ac, av); po::wcommand_line_parser parser(ac, av);
try { try {
po::store( po::store(
parser parser
.options(desc) .options(desc)
.style( .style(
po::command_line_style::unix_style | po::command_line_style::unix_style |
po::command_line_style::allow_long_disguise) po::command_line_style::allow_long_disguise)
.run(), .run(),
vm); vm);
vm.notify(); vm.notify();
} catch (std::exception& e) { } catch (const std::exception& e) {
std::cout << e.what() << '\n' << desc << '\n'; std::cout << e.what() << '\n' << desc << '\n';
return 3; return 3;
} }
@ -125,7 +120,7 @@ INT parseArguments(INT ac, WCHAR **av, po::variables_map& vm, printInfoStruct& p
if (vm.count("warning")) { if (vm.count("warning")) {
try { try {
printInfo.warn = threshold(vm["warning"].as<std::wstring>()); printInfo.warn = threshold(vm["warning"].as<std::wstring>());
} catch (std::invalid_argument& e) { } catch (const std::invalid_argument& e) {
std::cout << e.what() << '\n'; std::cout << e.what() << '\n';
return 3; return 3;
} }
@ -135,20 +130,19 @@ INT parseArguments(INT ac, WCHAR **av, po::variables_map& vm, printInfoStruct& p
if (vm.count("critical")) { if (vm.count("critical")) {
try { try {
printInfo.crit = threshold(vm["critical"].as<std::wstring>()); printInfo.crit = threshold(vm["critical"].as<std::wstring>());
} catch (std::invalid_argument& e) { } catch (const std::invalid_argument& e) {
std::cout << e.what() << '\n'; std::cout << e.what() << '\n';
return 3; return 3;
} }
printInfo.crit.legal = !printInfo.crit.legal; printInfo.crit.legal = !printInfo.crit.legal;
} }
if (vm.count("debug")) l_Debug = vm.count("debug") > 0;
debug = TRUE;
if (vm.count("unit")) { if (vm.count("unit")) {
try { try {
printInfo.unit = parseBUnit(vm["unit"].as<std::wstring>()); printInfo.unit = parseBUnit(vm["unit"].as<std::wstring>());
} catch (std::invalid_argument& e) { } catch (const std::invalid_argument& e) {
std::cout << e.what() << '\n'; std::cout << e.what() << '\n';
return 3; return 3;
} }
@ -157,9 +151,9 @@ INT parseArguments(INT ac, WCHAR **av, po::variables_map& vm, printInfoStruct& p
return -1; return -1;
} }
INT printOutput(printInfoStruct& printInfo) static int printOutput(printInfoStruct& printInfo)
{ {
if (debug) if (l_Debug)
std::wcout << L"Constructing output string" << '\n'; std::wcout << L"Constructing output string" << '\n';
state state = OK; state state = OK;
@ -191,13 +185,13 @@ INT printOutput(printInfoStruct& printInfo)
return state; return state;
} }
INT check_swap(printInfoStruct& printInfo) static int check_swap(printInfoStruct& printInfo)
{ {
MEMORYSTATUSEX MemBuf; MEMORYSTATUSEX MemBuf;
MemBuf.dwLength = sizeof(MemBuf); MemBuf.dwLength = sizeof(MemBuf);
if (!GlobalMemoryStatusEx(&MemBuf)) { if (!GlobalMemoryStatusEx(&MemBuf)) {
die(); printErrorInfo();
return 3; return 3;
} }
@ -207,3 +201,19 @@ INT check_swap(printInfoStruct& printInfo)
return -1; return -1;
} }
int wmain(int argc, WCHAR **argv)
{
printInfoStruct printInfo = { };
po::variables_map vm;
int ret = parseArguments(argc, argv, vm, printInfo);
if (ret != -1)
return ret;
ret = check_swap(printInfo);
if (ret != -1)
return ret;
return printOutput(printInfo);
}

View File

@ -1,37 +0,0 @@
/******************************************************************************
* Icinga 2 *
* Copyright (C) 2012-2018 Icinga Development Team (https://www.icinga.com/) *
* *
* This program is free software; you can redistribute it and/or *
* modify it under the terms of the GNU General Public License *
* as published by the Free Software Foundation; either version 2 *
* of the License, or (at your option) any later version. *
* *
* This program is distributed in the hope that it will be useful, *
* but WITHOUT ANY WARRANTY; without even the implied warranty of *
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
* GNU General Public License for more details. *
* *
* You should have received a copy of the GNU General Public License *
* along with this program; if not, write to the Free Software Foundation *
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA. *
******************************************************************************/
#ifndef CHECK_SWAP_H
#define CHECK_SWAP_H
#include "thresholds.h"
#include "boost/program_options.hpp"
struct printInfoStruct
{
threshold warn, crit;
DOUBLE tSwap, aSwap;
DOUBLE percentFree;
Bunit unit = BunitMB;
};
INT parseArguments(INT, WCHAR **, boost::program_options::variables_map&, printInfoStruct&);
INT printOutput(printInfoStruct&);
INT check_swap(printInfoStruct&);
#endif // !CHECK_SWAP_H

View File

@ -16,39 +16,34 @@
* along with this program; if not, write to the Free Software Foundation * * along with this program; if not, write to the Free Software Foundation *
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA. * * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA. *
******************************************************************************/ ******************************************************************************/
#include <windows.h>
#include <Shlwapi.h> #include "plugins/thresholds.hpp"
#include <boost/program_options.hpp>
#include <iostream> #include <iostream>
#include <windows.h>
#include <shlwapi.h>
#include <wuapi.h> #include <wuapi.h>
#include <wuerror.h> #include <wuerror.h>
#include "check_update.h"
#define VERSION 1.0 #define VERSION 1.0
#define CRITERIA L"(IsInstalled = 0 and CategoryIDs contains '0fa1201d-4330-4fa8-8ae9-b877473b6441') or (IsInstalled = 0 and CategoryIDs contains 'E6CF1350-C01B-414D-A61F-263D14D133B4')" #define CRITERIA L"(IsInstalled = 0 and CategoryIDs contains '0fa1201d-4330-4fa8-8ae9-b877473b6441') or (IsInstalled = 0 and CategoryIDs contains 'E6CF1350-C01B-414D-A61F-263D14D133B4')"
namespace po = boost::program_options; namespace po = boost::program_options;
static BOOL debug = FALSE; struct printInfoStruct
INT wmain(INT argc, WCHAR **argv)
{ {
printInfoStruct printInfo = { FALSE, FALSE, 0, FALSE, FALSE, FALSE }; bool warn{false};
po::variables_map vm; bool crit{false};
LONG numUpdates{0};
bool important{false};
bool reboot{false};
bool careForCanRequest{false};
};
INT ret = parseArguments(argc, argv, vm, printInfo); static bool l_Debug;
if (ret != -1)
return ret;
ret = check_update(printInfo); static int parseArguments(int ac, WCHAR **av, po::variables_map& vm, printInfoStruct& printInfo)
if (ret != -1)
return ret;
return printOutput(printInfo);
}
INT parseArguments(INT ac, WCHAR **av, po::variables_map& vm, printInfoStruct& printInfo)
{ {
WCHAR namePath[MAX_PATH]; WCHAR namePath[MAX_PATH];
GetModuleFileName(NULL, namePath, MAX_PATH); GetModuleFileName(NULL, namePath, MAX_PATH);
@ -65,19 +60,19 @@ INT parseArguments(INT ac, WCHAR **av, po::variables_map& vm, printInfoStruct& p
("possible-reboot", "Treat \"update may need reboot\" as \"update needs reboot\"") ("possible-reboot", "Treat \"update may need reboot\" as \"update needs reboot\"")
; ;
po::basic_command_line_parser<WCHAR> parser(ac, av); po::wcommand_line_parser parser(ac, av);
try { try {
po::store( po::store(
parser parser
.options(desc) .options(desc)
.style( .style(
po::command_line_style::unix_style | po::command_line_style::unix_style |
po::command_line_style::allow_long_disguise) po::command_line_style::allow_long_disguise)
.run(), .run(),
vm); vm);
vm.notify(); vm.notify();
} catch (std::exception& e) { } catch (const std::exception& e) {
std::cout << e.what() << '\n' << desc << '\n'; std::cout << e.what() << '\n' << desc << '\n';
return 3; return 3;
} }
@ -119,24 +114,18 @@ INT parseArguments(INT ac, WCHAR **av, po::variables_map& vm, printInfoStruct& p
return 0; return 0;
} }
if (vm.count("warning")) printInfo.warn = vm.count("warning") > 0;
printInfo.warn = TRUE; printInfo.crit = vm.count("critical") > 0;
printInfo.careForCanRequest = vm.count("possible-reboot") > 0;
if (vm.count("critical")) l_Debug = vm.count("debug") > 0;
printInfo.crit = TRUE;
if (vm.count("possible-reboot"))
printInfo.careForCanRequest = TRUE;
if (vm.count("debug"))
debug = TRUE;
return -1; return -1;
} }
INT printOutput(const printInfoStruct& printInfo) static int printOutput(const printInfoStruct& printInfo)
{ {
if (debug) if (l_Debug)
std::wcout << L"Constructing output string" << '\n'; std::wcout << L"Constructing output string" << '\n';
state state = OK; state state = OK;
@ -166,9 +155,9 @@ INT printOutput(const printInfoStruct& printInfo)
return state; return state;
} }
INT check_update(printInfoStruct& printInfo) static int check_update(printInfoStruct& printInfo)
{ {
if (debug) if (l_Debug)
std::wcout << "Initializing COM library" << '\n'; std::wcout << "Initializing COM library" << '\n';
CoInitializeEx(NULL, COINIT_APARTMENTTHREADED); CoInitializeEx(NULL, COINIT_APARTMENTTHREADED);
ISearchResult *pResult; ISearchResult *pResult;
@ -177,24 +166,24 @@ INT check_update(printInfoStruct& printInfo)
BSTR criteria = NULL; BSTR criteria = NULL;
HRESULT err; HRESULT err;
if (debug) if (l_Debug)
std::wcout << "Creating UpdateSession and UpdateSearcher" << '\n'; std::wcout << "Creating UpdateSession and UpdateSearcher" << '\n';
CoCreateInstance(CLSID_UpdateSession, NULL, CLSCTX_INPROC_SERVER, IID_IUpdateSession, (LPVOID*)&pSession); CoCreateInstance(CLSID_UpdateSession, NULL, CLSCTX_INPROC_SERVER, IID_IUpdateSession, (void **)&pSession);
pSession->CreateUpdateSearcher(&pSearcher); pSession->CreateUpdateSearcher(&pSearcher);
/* /*
* IsInstalled = 0: All updates, including languagepacks and features * IsInstalled = 0: All updates, including languagepacks and features
* BrowseOnly = 0: No features or languagepacks, security and unnamed * BrowseOnly = 0: No features or languagepacks, security and unnamed
* BrowseOnly = 1: Nothing, broken * BrowseOnly = 1: Nothing, broken
* RebootRequired = 1: Reboot required * RebootRequired = 1: Reboot required
*/ */
criteria = SysAllocString(CRITERIA); criteria = SysAllocString(CRITERIA);
// https://msdn.microsoft.com/en-us/library/windows/desktop/aa386526%28v=vs.85%29.aspx // https://msdn.microsoft.com/en-us/library/windows/desktop/aa386526%28v=vs.85%29.aspx
// https://msdn.microsoft.com/en-us/library/ff357803%28v=vs.85%29.aspx // https://msdn.microsoft.com/en-us/library/ff357803%28v=vs.85%29.aspx
if (debug) if (l_Debug)
std::wcout << L"Querrying updates from server" << '\n'; std::wcout << L"Querying updates from server" << '\n';
err = pSearcher->Search(criteria, &pResult); err = pSearcher->Search(criteria, &pResult);
if (!SUCCEEDED(err)) if (!SUCCEEDED(err))
@ -212,31 +201,31 @@ INT check_update(printInfoStruct& printInfo)
return -1; return -1;
printInfo.numUpdates = updateSize; printInfo.numUpdates = updateSize;
// printInfo.important = printInfo.warn; // printInfo.important = printInfo.warn;
IInstallationBehavior *pIbehav; IInstallationBehavior *pIbehav;
InstallationRebootBehavior updateReboot; InstallationRebootBehavior updateReboot;
for (LONG i = 0; i < updateSize; i++) { for (LONG i = 0; i < updateSize; i++) {
pCollection->get_Item(i, &pUpdate); pCollection->get_Item(i, &pUpdate);
if (debug) { if (l_Debug) {
std::wcout << L"Checking reboot behaviour of update number " << i << '\n'; std::wcout << L"Checking reboot behaviour of update number " << i << '\n';
} }
pUpdate->get_InstallationBehavior(&pIbehav); pUpdate->get_InstallationBehavior(&pIbehav);
pIbehav->get_RebootBehavior(&updateReboot); pIbehav->get_RebootBehavior(&updateReboot);
if (updateReboot == irbAlwaysRequiresReboot) { if (updateReboot == irbAlwaysRequiresReboot) {
printInfo.reboot = TRUE; printInfo.reboot = true;
if (debug) if (l_Debug)
std::wcout << L"It requires reboot" << '\n'; std::wcout << L"It requires reboot" << '\n';
continue; continue;
} }
if (printInfo.careForCanRequest && updateReboot == irbCanRequestReboot) if (printInfo.careForCanRequest && updateReboot == irbCanRequestReboot)
if (debug) if (l_Debug)
std::wcout << L"It requires reboot" << '\n'; std::wcout << L"It requires reboot" << '\n';
printInfo.reboot = TRUE; printInfo.reboot = true;
} }
if (debug) if (l_Debug)
std::wcout << L"Cleaning up and returning" << '\n'; std::wcout << L"Cleaning up and returning" << '\n';
SysFreeString(criteria); SysFreeString(criteria);
@ -244,9 +233,25 @@ INT check_update(printInfoStruct& printInfo)
return -1; return -1;
die: die:
die(err); printErrorInfo(err);
CoUninitialize(); CoUninitialize();
if (criteria) if (criteria)
SysFreeString(criteria); SysFreeString(criteria);
return 3; return 3;
} }
int wmain(int argc, WCHAR **argv)
{
printInfoStruct printInfo;
po::variables_map vm;
int ret = parseArguments(argc, argv, vm, printInfo);
if (ret != -1)
return ret;
ret = check_update(printInfo);
if (ret != -1)
return ret;
return printOutput(printInfo);
}

View File

@ -1,36 +0,0 @@
/******************************************************************************
* Icinga 2 *
* Copyright (C) 2012-2018 Icinga Development Team (https://www.icinga.com/) *
* *
* This program is free software; you can redistribute it and/or *
* modify it under the terms of the GNU General Public License *
* as published by the Free Software Foundation; either version 2 *
* of the License, or (at your option) any later version. *
* *
* This program is distributed in the hope that it will be useful, *
* but WITHOUT ANY WARRANTY; without even the implied warranty of *
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
* GNU General Public License for more details. *
* *
* You should have received a copy of the GNU General Public License *
* along with this program; if not, write to the Free Software Foundation *
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA. *
******************************************************************************/
#ifndef CHECK_UPDATE_H
#define CHECK_UPDATE_H
#include "thresholds.h"
#include "boost/program_options.hpp"
struct printInfoStruct
{
BOOL warn, crit;
LONG numUpdates;
BOOL important, reboot, careForCanRequest;
};
INT parseArguments(INT, WCHAR **, boost::program_options::variables_map&, printInfoStruct&);
INT printOutput(CONST printInfoStruct&);
INT check_update(printInfoStruct&);
#endif // !CHECK_UPDATE_H

View File

@ -16,35 +16,29 @@
* along with this program; if not, write to the Free Software Foundation * * along with this program; if not, write to the Free Software Foundation *
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA. * * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA. *
******************************************************************************/ ******************************************************************************/
#include <Windows.h>
#include <Shlwapi.h> #include "plugins/thresholds.hpp"
#include <boost/program_options.hpp>
#include <boost/chrono.hpp>
#include <iostream> #include <iostream>
#include <windows.h>
#include "check_uptime.h" #include <shlwapi.h>
#include "boost/chrono.hpp"
#define VERSION 1.0 #define VERSION 1.0
namespace po = boost::program_options; namespace po = boost::program_options;
static BOOL debug; struct printInfoStruct
INT wmain(INT argc, WCHAR **argv)
{ {
po::variables_map vm; threshold warn;
printInfoStruct printInfo = { }; threshold crit;
INT ret = parseArguments(argc, argv, vm, printInfo); long long time;
Tunit unit;
};
if (ret != -1) static bool l_Debug;
return ret;
getUptime(printInfo); static int parseArguments(int ac, WCHAR **av, po::variables_map& vm, printInfoStruct& printInfo)
return printOutput(printInfo);
}
INT parseArguments(INT ac, WCHAR **av, po::variables_map& vm, printInfoStruct& printInfo)
{ {
WCHAR namePath[MAX_PATH]; WCHAR namePath[MAX_PATH];
GetModuleFileName(NULL, namePath, MAX_PATH); GetModuleFileName(NULL, namePath, MAX_PATH);
@ -61,19 +55,19 @@ INT parseArguments(INT ac, WCHAR **av, po::variables_map& vm, printInfoStruct& p
("unit,u", po::wvalue<std::wstring>(), "Unit to use:\nh\t- hours\nm\t- minutes\ns\t- seconds (default)\nms\t- milliseconds") ("unit,u", po::wvalue<std::wstring>(), "Unit to use:\nh\t- hours\nm\t- minutes\ns\t- seconds (default)\nms\t- milliseconds")
; ;
po::basic_command_line_parser<WCHAR> parser(ac, av); po::wcommand_line_parser parser(ac, av);
try { try {
po::store( po::store(
parser parser
.options(desc) .options(desc)
.style( .style(
po::command_line_style::unix_style | po::command_line_style::unix_style |
po::command_line_style::allow_long_disguise) po::command_line_style::allow_long_disguise)
.run(), .run(),
vm); vm);
vm.notify(); vm.notify();
} catch (std::exception& e) { } catch (const std::exception& e) {
std::cout << e.what() << '\n' << desc << '\n'; std::cout << e.what() << '\n' << desc << '\n';
return 3; return 3;
} }
@ -117,7 +111,7 @@ INT parseArguments(INT ac, WCHAR **av, po::variables_map& vm, printInfoStruct& p
L"to end with a percentage sign.\n\n" L"to end with a percentage sign.\n\n"
L"All of these options work with the critical threshold \"-c\" too.\n" L"All of these options work with the critical threshold \"-c\" too.\n"
, progName); , progName);
std::cout << '\n'; std::cout << '\n';
return 0; return 0;
} }
@ -129,7 +123,7 @@ INT parseArguments(INT ac, WCHAR **av, po::variables_map& vm, printInfoStruct& p
if (vm.count("warning")) { if (vm.count("warning")) {
try { try {
printInfo.warn = threshold(vm["warning"].as<std::wstring>()); printInfo.warn = threshold(vm["warning"].as<std::wstring>());
} catch (std::invalid_argument& e) { } catch (const std::invalid_argument& e) {
std::cout << e.what() << '\n'; std::cout << e.what() << '\n';
return 3; return 3;
} }
@ -137,31 +131,30 @@ INT parseArguments(INT ac, WCHAR **av, po::variables_map& vm, printInfoStruct& p
if (vm.count("critical")) { if (vm.count("critical")) {
try { try {
printInfo.crit = threshold(vm["critical"].as<std::wstring>()); printInfo.crit = threshold(vm["critical"].as<std::wstring>());
} catch (std::invalid_argument& e) { } catch (const std::invalid_argument& e) {
std::cout << e.what() << '\n'; std::cout << e.what() << '\n';
return 3; return 3;
} }
} }
if (vm.count("unit")) { if (vm.count("unit")) {
try{ try {
printInfo.unit = parseTUnit(vm["unit"].as<std::wstring>()); printInfo.unit = parseTUnit(vm["unit"].as<std::wstring>());
} catch (std::invalid_argument) { } catch (const std::invalid_argument&) {
std::wcout << L"Unknown unit type " << vm["unit"].as<std::wstring>() << '\n'; std::wcout << L"Unknown unit type " << vm["unit"].as<std::wstring>() << '\n';
return 3; return 3;
} }
} else } else
printInfo.unit = TunitS; printInfo.unit = TunitS;
if (vm.count("debug")) l_Debug = vm.count("debug") > 0;
debug = TRUE;
return -1; return -1;
} }
INT printOutput(printInfoStruct& printInfo) static int printOutput(printInfoStruct& printInfo)
{ {
if (debug) if (l_Debug)
std::wcout << L"Constructing output string" << '\n'; std::wcout << L"Constructing output string" << '\n';
state state = OK; state state = OK;
@ -192,14 +185,14 @@ INT printOutput(printInfoStruct& printInfo)
return state; return state;
} }
VOID getUptime(printInfoStruct& printInfo) static void getUptime(printInfoStruct& printInfo)
{ {
if (debug) if (l_Debug)
std::wcout << L"Getting uptime in milliseconds" << '\n'; std::wcout << L"Getting uptime in milliseconds" << '\n';
boost::chrono::milliseconds uptime = boost::chrono::milliseconds(GetTickCount64()); boost::chrono::milliseconds uptime = boost::chrono::milliseconds(GetTickCount64());
if (debug) if (l_Debug)
std::wcout << L"Converting requested unit (default: seconds)" << '\n'; std::wcout << L"Converting requested unit (default: seconds)" << '\n';
switch (printInfo.unit) { switch (printInfo.unit) {
@ -217,3 +210,17 @@ VOID getUptime(printInfoStruct& printInfo)
break; break;
} }
} }
int wmain(int argc, WCHAR **argv)
{
po::variables_map vm;
printInfoStruct printInfo;
int ret = parseArguments(argc, argv, vm, printInfo);
if (ret != -1)
return ret;
getUptime(printInfo);
return printOutput(printInfo);
}

View File

@ -1,36 +0,0 @@
/******************************************************************************
* Icinga 2 *
* Copyright (C) 2012-2018 Icinga Development Team (https://www.icinga.com/) *
* *
* This program is free software; you can redistribute it and/or *
* modify it under the terms of the GNU General Public License *
* as published by the Free Software Foundation; either version 2 *
* of the License, or (at your option) any later version. *
* *
* This program is distributed in the hope that it will be useful, *
* but WITHOUT ANY WARRANTY; without even the implied warranty of *
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
* GNU General Public License for more details. *
* *
* You should have received a copy of the GNU General Public License *
* along with this program; if not, write to the Free Software Foundation *
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA. *
******************************************************************************/
#ifndef CHECK_UPTIME_H
#define CHECK_UPTIME_H
#include "thresholds.h"
#include "boost/program_options.hpp"
struct printInfoStruct
{
threshold warn, crit;
long long time;
Tunit unit;
};
INT parseArguments(INT, WCHAR **, boost::program_options::variables_map&, printInfoStruct&);
INT printOutput(printInfoStruct&);
VOID getUptime(printInfoStruct&);
#endif // !CHECK_UPTIME_H

View File

@ -16,36 +16,28 @@
* along with this program; if not, write to the Free Software Foundation * * along with this program; if not, write to the Free Software Foundation *
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA. * * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA. *
******************************************************************************/ ******************************************************************************/
#include <Windows.h>
#include <Shlwapi.h>
#include <wtsapi32.h>
#include <iostream>
#include "check_users.h" #include "plugins/thresholds.hpp"
#include <boost/program_options.hpp>
#include <iostream>
#include <windows.h>
#include <shlwapi.h>
#include <wtsapi32.h>
#define VERSION 1.0 #define VERSION 1.0
namespace po = boost::program_options; namespace po = boost::program_options;
static BOOL debug = FALSE; struct printInfoStruct
INT wmain(INT argc, WCHAR **argv)
{ {
printInfoStruct printInfo = { }; threshold warn;
po::variables_map vm; threshold crit;
DOUBLE users;
};
INT ret = parseArguments(argc, argv, vm, printInfo); static bool l_Debug;
if (ret != -1)
return ret;
ret = check_users(printInfo); static int parseArguments(int ac, WCHAR **av, po::variables_map& vm, printInfoStruct& printInfo)
if (ret != -1)
return ret;
return printOutput(printInfo);
}
INT parseArguments(INT ac, WCHAR **av, po::variables_map& vm, printInfoStruct& printInfo)
{ {
WCHAR namePath[MAX_PATH]; WCHAR namePath[MAX_PATH];
GetModuleFileName(NULL, namePath, MAX_PATH); GetModuleFileName(NULL, namePath, MAX_PATH);
@ -61,19 +53,19 @@ INT parseArguments(INT ac, WCHAR **av, po::variables_map& vm, printInfoStruct& p
("critical,c", po::wvalue<std::wstring>(), "Critical threshold") ("critical,c", po::wvalue<std::wstring>(), "Critical threshold")
; ;
po::basic_command_line_parser<WCHAR> parser(ac, av); po::wcommand_line_parser parser(ac, av);
try { try {
po::store( po::store(
parser parser
.options(desc) .options(desc)
.style( .style(
po::command_line_style::unix_style | po::command_line_style::unix_style |
po::command_line_style::allow_long_disguise) po::command_line_style::allow_long_disguise)
.run(), .run(),
vm); vm);
vm.notify(); vm.notify();
} catch (std::exception& e) { } catch (const std::exception& e) {
std::cout << e.what() << '\n' << desc << '\n'; std::cout << e.what() << '\n' << desc << '\n';
return 3; return 3;
} }
@ -125,7 +117,7 @@ INT parseArguments(INT ac, WCHAR **av, po::variables_map& vm, printInfoStruct& p
if (vm.count("warning")) { if (vm.count("warning")) {
try { try {
printInfo.warn = threshold(vm["warning"].as<std::wstring>()); printInfo.warn = threshold(vm["warning"].as<std::wstring>());
} catch (std::invalid_argument& e) { } catch (const std::invalid_argument& e) {
std::cout << e.what() << '\n'; std::cout << e.what() << '\n';
return 3; return 3;
} }
@ -133,21 +125,20 @@ INT parseArguments(INT ac, WCHAR **av, po::variables_map& vm, printInfoStruct& p
if (vm.count("critical")) { if (vm.count("critical")) {
try { try {
printInfo.crit = threshold(vm["critical"].as<std::wstring>()); printInfo.crit = threshold(vm["critical"].as<std::wstring>());
} catch (std::invalid_argument& e) { } catch (const std::invalid_argument& e) {
std::cout << e.what() << '\n'; std::cout << e.what() << '\n';
return 3; return 3;
} }
} }
if (vm.count("debug")) l_Debug = vm.count("debug") > 0;
debug = TRUE;
return -1; return -1;
} }
INT printOutput(printInfoStruct& printInfo) static int printOutput(printInfoStruct& printInfo)
{ {
if (debug) if (l_Debug)
std::wcout << L"Constructing output string" << '\n'; std::wcout << L"Constructing output string" << '\n';
state state = OK; state state = OK;
@ -176,40 +167,40 @@ INT printOutput(printInfoStruct& printInfo)
return state; return state;
} }
INT check_users(printInfoStruct& printInfo) static int check_users(printInfoStruct& printInfo)
{ {
DOUBLE users = 0; DOUBLE users = 0;
WTS_SESSION_INFOW *pSessionInfo = NULL; WTS_SESSION_INFOW *pSessionInfo = NULL;
DWORD count; DWORD count;
DWORD index; DWORD index;
if (debug) if (l_Debug)
std::wcout << L"Trying to enumerate terminal sessions" << '\n'; std::wcout << L"Trying to enumerate terminal sessions" << '\n';
if (!WTSEnumerateSessions(WTS_CURRENT_SERVER_HANDLE, 0, 1, &pSessionInfo, &count)) { if (!WTSEnumerateSessions(WTS_CURRENT_SERVER_HANDLE, 0, 1, &pSessionInfo, &count)) {
std::wcout << L"Failed to enumerate terminal sessions" << '\n'; std::wcout << L"Failed to enumerate terminal sessions" << '\n';
die(); printErrorInfo();
if (pSessionInfo) if (pSessionInfo)
WTSFreeMemory(pSessionInfo); WTSFreeMemory(pSessionInfo);
return 3; return 3;
} }
if (debug) if (l_Debug)
std::wcout << L"Got all sessions (" << count << L"), traversing and counting active ones" << '\n'; std::wcout << L"Got all sessions (" << count << L"), traversing and counting active ones" << '\n';
for (index = 0; index < count; index++) { for (index = 0; index < count; index++) {
LPWSTR name; LPWSTR name;
DWORD size; DWORD size;
INT len; int len;
if (debug) if (l_Debug)
std::wcout << L"Querrying session number " << index << '\n'; std::wcout << L"Querrying session number " << index << '\n';
if (!WTSQuerySessionInformation(WTS_CURRENT_SERVER_HANDLE, pSessionInfo[index].SessionId, if (!WTSQuerySessionInformation(WTS_CURRENT_SERVER_HANDLE, pSessionInfo[index].SessionId,
WTSUserName, &name, &size)) WTSUserName, &name, &size))
continue; continue;
if (debug) if (l_Debug)
std::wcout << L"Found \"" << name << L"\". Checking whether it's a real session" << '\n'; std::wcout << L"Found \"" << name << L"\". Checking whether it's a real session" << '\n';
len = lstrlenW(name); len = lstrlenW(name);
@ -221,15 +212,31 @@ INT check_users(printInfoStruct& printInfo)
if (pSessionInfo[index].State == WTSActive || pSessionInfo[index].State == WTSDisconnected) { if (pSessionInfo[index].State == WTSActive || pSessionInfo[index].State == WTSDisconnected) {
users++; users++;
if (debug) if (l_Debug)
std::wcout << L"\"" << name << L"\" is a real session, counting it. Now " << users << '\n'; std::wcout << L"\"" << name << L"\" is a real session, counting it. Now " << users << '\n';
} }
} }
if (debug) if (l_Debug)
std::wcout << "Finished coutning user sessions (" << users << "). Freeing memory and returning" << '\n'; std::wcout << "Finished coutning user sessions (" << users << "). Freeing memory and returning" << '\n';
WTSFreeMemory(pSessionInfo); WTSFreeMemory(pSessionInfo);
printInfo.users = users; printInfo.users = users;
return -1; return -1;
} }
int wmain(int argc, WCHAR **argv)
{
printInfoStruct printInfo = { };
po::variables_map vm;
int ret = parseArguments(argc, argv, vm, printInfo);
if (ret != -1)
return ret;
ret = check_users(printInfo);
if (ret != -1)
return ret;
return printOutput(printInfo);
}

View File

@ -1,36 +0,0 @@
/******************************************************************************
* Icinga 2 *
* Copyright (C) 2012-2018 Icinga Development Team (https://www.icinga.com/) *
* *
* This program is free software; you can redistribute it and/or *
* modify it under the terms of the GNU General Public License *
* as published by the Free Software Foundation; either version 2 *
* of the License, or (at your option) any later version. *
* *
* This program is distributed in the hope that it will be useful, *
* but WITHOUT ANY WARRANTY; without even the implied warranty of *
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
* GNU General Public License for more details. *
* *
* You should have received a copy of the GNU General Public License *
* along with this program; if not, write to the Free Software Foundation *
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA. *
******************************************************************************/
#ifndef CHECK_USERS_H
#define CHECK_USERS_H
#include "thresholds.h"
#include <boost/program_options.hpp>
struct printInfoStruct
{
threshold warn, crit;
DOUBLE users;
};
INT parseArguments(INT, WCHAR **, boost::program_options::variables_map&, printInfoStruct&);
INT printOutput(printInfoStruct&);
INT check_users(printInfoStruct&);
#endif /* CHECK_USERS_H */

View File

@ -17,7 +17,7 @@
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA. * * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA. *
******************************************************************************/ ******************************************************************************/
#include "thresholds.h" #include "plugins/thresholds.hpp"
#include <boost/algorithm/string.hpp> #include <boost/algorithm/string.hpp>
#include <boost/lexical_cast.hpp> #include <boost/lexical_cast.hpp>
#include <iostream> #include <iostream>
@ -28,7 +28,7 @@ threshold::threshold()
: set(false) : set(false)
{} {}
threshold::threshold(CONST std::wstring& stri) threshold::threshold(const std::wstring& stri)
{ {
if (stri.empty()) if (stri.empty())
throw std::invalid_argument("Threshold must not be empty"); throw std::invalid_argument("Threshold must not be empty");
@ -64,7 +64,7 @@ threshold::threshold(CONST std::wstring& stri)
boost::algorithm::trim(str2); boost::algorithm::trim(str2);
upper = boost::lexical_cast<DOUBLE>(str2); upper = boost::lexical_cast<DOUBLE>(str2);
legal = !low; perc = pc; set = true; legal = !low; perc = pc; set = true;
} catch (CONST boost::bad_lexical_cast&) { } catch (const boost::bad_lexical_cast&) {
throw std::invalid_argument("Unknown Threshold type"); throw std::invalid_argument("Unknown Threshold type");
} }
} else { //not range } else { //not range
@ -76,17 +76,17 @@ threshold::threshold(CONST std::wstring& stri)
boost::algorithm::trim(str); boost::algorithm::trim(str);
lower = upper = boost::lexical_cast<DOUBLE>(str); lower = upper = boost::lexical_cast<DOUBLE>(str);
legal = !low; perc = pc; set = true; legal = !low; perc = pc; set = true;
} catch (CONST boost::bad_lexical_cast&) { } catch (const boost::bad_lexical_cast&) {
throw std::invalid_argument("Unknown Threshold type"); throw std::invalid_argument("Unknown Threshold type");
} }
} }
} }
//return TRUE if the threshold is broken //return TRUE if the threshold is broken
BOOL threshold::rend(CONST DOUBLE val, CONST DOUBLE max) bool threshold::rend(const double val, const double max)
{ {
DOUBLE upperAbs = upper; double upperAbs = upper;
DOUBLE lowerAbs = lower; double lowerAbs = lower;
if (perc) { if (perc) {
upperAbs = upper / 100.0 * max; upperAbs = upper / 100.0 * max;
@ -102,13 +102,13 @@ BOOL threshold::rend(CONST DOUBLE val, CONST DOUBLE max)
} }
//returns a printable string of the threshold //returns a printable string of the threshold
std::wstring threshold::pString(CONST DOUBLE max) std::wstring threshold::pString(const double max)
{ {
if (!set) if (!set)
return L""; return L"";
//transform percentages to abolute values //transform percentages to abolute values
DOUBLE lowerAbs = lower; double lowerAbs = lower;
DOUBLE upperAbs = upper; double upperAbs = upper;
if (perc) { if (perc) {
lowerAbs = lower / 100.0 * max; lowerAbs = lower / 100.0 * max;
upperAbs = upper / 100.0 * max; upperAbs = upper / 100.0 * max;
@ -126,7 +126,7 @@ std::wstring threshold::pString(CONST DOUBLE max)
return s; return s;
} }
std::wstring removeZero(DOUBLE val) std::wstring removeZero(double val)
{ {
std::wstring ret = boost::lexical_cast<std::wstring>(val); std::wstring ret = boost::lexical_cast<std::wstring>(val);
std::wstring::size_type pos = ret.length(); std::wstring::size_type pos = ret.length();
@ -144,14 +144,14 @@ std::wstring removeZero(DOUBLE val)
return L"0"; return L"0";
} }
std::vector<std::wstring> splitMultiOptions(std::wstring str) std::vector<std::wstring> splitMultiOptions(const std::wstring& str)
{ {
std::vector<std::wstring> sVec; std::vector<std::wstring> sVec;
boost::split(sVec, str, boost::is_any_of(L",")); boost::split(sVec, str, boost::is_any_of(L","));
return sVec; return sVec;
} }
Bunit parseBUnit(CONST std::wstring& str) Bunit parseBUnit(const std::wstring& str)
{ {
std::wstring wstr = to_upper_copy(str); std::wstring wstr = to_upper_copy(str);
@ -169,7 +169,7 @@ Bunit parseBUnit(CONST std::wstring& str)
throw std::invalid_argument("Unknown unit type"); throw std::invalid_argument("Unknown unit type");
} }
std::wstring BunitStr(CONST Bunit& unit) std::wstring BunitStr(const Bunit& unit)
{ {
switch (unit) { switch (unit) {
case BunitB: case BunitB:
@ -186,7 +186,7 @@ std::wstring BunitStr(CONST Bunit& unit)
return NULL; return NULL;
} }
Tunit parseTUnit(CONST std::wstring& str) { Tunit parseTUnit(const std::wstring& str) {
std::wstring wstr = to_lower_copy(str); std::wstring wstr = to_lower_copy(str);
if (wstr == L"ms") if (wstr == L"ms")
@ -201,7 +201,7 @@ Tunit parseTUnit(CONST std::wstring& str) {
throw std::invalid_argument("Unknown unit type"); throw std::invalid_argument("Unknown unit type");
} }
std::wstring TunitStr(CONST Tunit& unit) std::wstring TunitStr(const Tunit& unit)
{ {
switch (unit) { switch (unit) {
case TunitMS: case TunitMS:
@ -216,7 +216,7 @@ std::wstring TunitStr(CONST Tunit& unit)
return NULL; return NULL;
} }
VOID die(DWORD err) void printErrorInfo(unsigned long err)
{ {
if (!err) if (!err)
err = GetLastError(); err = GetLastError();

View File

@ -1,73 +0,0 @@
/******************************************************************************
* Icinga 2 *
* Copyright (C) 2012-2018 Icinga Development Team (https://www.icinga.com/) *
* *
* This program is free software; you can redistribute it and/or *
* modify it under the terms of the GNU General Public License *
* as published by the Free Software Foundation; either version 2 *
* of the License, or (at your option) any later version. *
* *
* This program is distributed in the hope that it will be useful, *
* but WITHOUT ANY WARRANTY; without even the implied warranty of *
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
* GNU General Public License for more details. *
* *
* You should have received a copy of the GNU General Public License *
* along with this program; if not, write to the Free Software Foundation *
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA. *
******************************************************************************/
#ifndef THRESHOLDS_H
#define THRESHOLDS_H
#include <string>
#include <Windows.h>
#include <vector>
enum Bunit
{
BunitB = 0, BunitkB = 1, BunitMB = 2, BunitGB = 3, BunitTB = 4
};
enum Tunit
{
TunitMS, TunitS, TunitM, TunitH
};
enum state
{
OK = 0, WARNING = 1, CRITICAL = 2
};
class threshold
{
public:
//DOUBLEs are always enough for ANY 64 bit value
DOUBLE lower, upper;
//TRUE means everything BELOW upper/outside [lower-upper] is fine
BOOL legal, perc, set;
threshold();
threshold(CONST DOUBLE v, CONST DOUBLE c, BOOL l = TRUE, BOOL p = FALSE);
threshold(CONST std::wstring&);
//return TRUE if the threshold is broken
BOOL rend(CONST DOUBLE val, CONST DOUBLE max = 100.0);
//returns a printable string of the threshold
std::wstring pString(CONST DOUBLE max = 100.0);
};
std::wstring removeZero(DOUBLE);
std::vector<std::wstring> splitMultiOptions(std::wstring);
Bunit parseBUnit(CONST std::wstring&);
std::wstring BunitStr(CONST Bunit&);
Tunit parseTUnit(CONST std::wstring&);
std::wstring TunitStr(CONST Tunit&);
VOID die(DWORD err = 0);
#endif /* THRESHOLDS_H */

View File

@ -17,37 +17,61 @@
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA. * * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA. *
******************************************************************************/ ******************************************************************************/
#ifndef CHECK_DISK_H #ifndef THRESHOLDS_H
#define CHECK_DISK_H #define THRESHOLDS_H
#include <Windows.h> #include <string>
#include <vector> #include <vector>
#include <windows.h>
#include "boost/program_options.hpp" enum Bunit
#include "thresholds.h"
struct drive
{ {
std::wstring name; BunitB = 0, BunitkB = 1, BunitMB = 2, BunitGB = 3, BunitTB = 4
double cap, free, used;
drive(std::wstring p)
: name(p)
{
}
}; };
struct printInfoStruct enum Tunit
{ {
threshold warn, crit; TunitMS, TunitS, TunitM, TunitH
std::vector<std::wstring> drives, exclude_drives;
Bunit unit;
BOOL showUsed;
}; };
static INT parseArguments(int, wchar_t **, boost::program_options::variables_map&, printInfoStruct&); enum state
static INT printOutput(printInfoStruct&, std::vector<drive>&); {
static INT check_drives(std::vector<drive>&, std::vector<std::wstring>&); OK = 0, WARNING = 1, CRITICAL = 2
static INT check_drives(std::vector<drive>&, printInfoStruct&); };
static BOOL getDriveSpaceValues(drive&, const Bunit&);
static bool checkName(const drive& d, const std::wstring& s); class threshold
#endif /*CHECK_DISK_H*/ {
public:
// doubles are always enough for ANY 64 bit value
double lower;
double upper;
// true means everything BELOW upper/outside [lower-upper] is fine
bool legal;
bool perc;
bool set;
threshold();
threshold(const double v, const double c, bool l = true, bool p = false);
threshold(const std::wstring&);
// returns true if the threshold is broken
bool rend(const double val, const double max = 100.0);
// returns a printable string of the threshold
std::wstring pString(const double max = 100.0);
};
std::wstring removeZero(double);
std::vector<std::wstring> splitMultiOptions(const std::wstring&);
Bunit parseBUnit(const std::wstring&);
std::wstring BunitStr(const Bunit&);
Tunit parseTUnit(const std::wstring&);
std::wstring TunitStr(const Tunit&);
void printErrorInfo(unsigned long err = 0);
#endif /* THRESHOLDS_H */