From a0960c84cabc3f2b648ba113c029d792d8441088 Mon Sep 17 00:00:00 2001 From: Imanol-Mikel Barba Sabariego Date: Mon, 30 May 2016 00:22:26 +0200 Subject: [PATCH] Developed plugin for upnp --- CMakeLists.txt | 4 ++-- check_upnp/README.md | 23 +++++++++++++++++++++++ check_upnp/auxiliar.cpp | 55 +++++++++++++++++++++++++++++++++++++++++++++++++++++++ check_upnp/auxiliar.h | 35 +++++++++++++++++++++++++++++++++++ check_upnp/check_upnp.cpp | 145 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ check_upnp/check_upnp.h | 25 +++++++++++++++++++++++++ check_upnp/udp.cpp | 39 +++++++++++++++++++++++++++++++++++++++ check_upnp/udp.h | 22 ++++++++++++++++++++++ 8 files changed, 346 insertions(+), 2 deletions(-) create mode 100755 check_upnp/README.md create mode 100755 check_upnp/auxiliar.cpp create mode 100755 check_upnp/auxiliar.h create mode 100755 check_upnp/check_upnp.cpp create mode 100755 check_upnp/check_upnp.h create mode 100644 check_upnp/udp.cpp create mode 100644 check_upnp/udp.h diff --git a/CMakeLists.txt b/CMakeLists.txt index f65e482..a227283 100755 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -6,8 +6,8 @@ set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=c++11 -U__STRICT_ANSI__") set(SOURCE_FILES_CSGO check_csgo/check_csgo.cpp check_csgo/auxiliar.cpp check_csgo/udp.cpp) add_executable(check_csgo ${SOURCE_FILES_CSGO}) -set(SOURCE_FILES_NFS4 check_nfs4/check_nfs4.cpp check_csgo/auxiliar.cpp check_csgo/udp.cpp) -add_executable(check_nfs4 ${SOURCE_FILES_NFS4}) +set(SOURCE_FILES_UPNP check_upnp/check_upnp.cpp check_upnp/auxiliar.cpp check_upnp/udp.cpp) +add_executable(check_upnp ${SOURCE_FILES_UPNP}) set(SOURCE_FILES_MEMFREE check_memfree/check_memfree.cpp check_memfree/range.cpp check_memfree/auxiliar.cpp) add_executable(check_memfree ${SOURCE_FILES_MEMFREE}) diff --git a/check_upnp/README.md b/check_upnp/README.md new file mode 100755 index 0000000..281556b --- /dev/null +++ b/check_upnp/README.md @@ -0,0 +1,23 @@ +``` +check_memfree v1.0 + +Check free memory space on local machine. + +Usage: +check_memfree [-hV] -w % -c % +check_memfree [-hV] -w -c + +Options: + -h + Print detailed help screen + -V + Print version information + -w INTEGER + Exit with WARNING status if less than INTEGER bytes of memory space are free + -w PERCENT% + Exit with WARNING status if less than PERCENT of memory space is free + -c INTEGER + Exit with CRITICAL status if less than INTEGER bytes of memory space are free + -c PERCENT% + Exit with CRITCAL status if less than PERCENT of memory space is free +``` diff --git a/check_upnp/auxiliar.cpp b/check_upnp/auxiliar.cpp new file mode 100755 index 0000000..53aca90 --- /dev/null +++ b/check_upnp/auxiliar.cpp @@ -0,0 +1,55 @@ +// +// Created by Imanol on 28-may-16. +// + +#include "auxiliar.h" + +void timer_handler (int signum) +{ + if(signum == SIGVTALRM) + { + cout << servicename << " CRITICAL - timeout occurred" << endl; + exit(2); + } +} + +int str2int(string str) +{ + int num; + stringstream sstream; + sstream << str; + if(!(sstream >> num)) + { + throw integerConversionException("Integer conversion error"); + } + return num; +} + +string int2str(int x) +{ + string str; + stringstream sstream; + sstream << x; + sstream >> str; + return str; +} + +int exec(string cmd, string *output) +{ + *output = ""; + FILE* pipe = popen(cmd.c_str(), "r"); + if (!pipe) + { + cout << "Error opening child process" << endl; + exit(3); + } + char buffer[128]; + while(!feof(pipe)) + { + if(fgets(buffer, 128, pipe) != NULL) + { + *output += buffer; + } + } + return pclose(pipe)/256; +} \ No newline at end of file diff --git a/check_upnp/auxiliar.h b/check_upnp/auxiliar.h new file mode 100755 index 0000000..6cc6e6a --- /dev/null +++ b/check_upnp/auxiliar.h @@ -0,0 +1,35 @@ +// +// Created by Imanol on 28-may-16. +// + +#ifndef NAGIOS_PLUGINS_AUXILIAR_H +#define NAGIOS_PLUGINS_AUXILIAR_H + +#include +#include +#include + +#include +#include +#include + +using namespace std; + +extern char *servicename; + +int str2int(string str); +string int2str(int x); +int exec(string cmd, string *output); +void timer_handler (int signum); + +class integerConversionException : public exception +{ +private: + string s; +public: + integerConversionException(std::string ss) : s(ss) {} + ~integerConversionException() throw () {} + const char* what() const throw() { return s.c_str(); } +}; + +#endif //NAGIOS_PLUGINS_AUXILIAR_H diff --git a/check_upnp/check_upnp.cpp b/check_upnp/check_upnp.cpp new file mode 100755 index 0000000..9c82ac3 --- /dev/null +++ b/check_upnp/check_upnp.cpp @@ -0,0 +1,145 @@ +#include "check_upnp.h" + +using namespace std; + +char *servicename = (char*)"UPnP"; + +void printVersion() +{ + cout << "check_upnp v" << VERSION << endl << endl; +} + +void printHelp(bool longVersion) +{ + if(longVersion) + { + printVersion(); + cout << "Check CS:GO DS instance." << endl << endl; + printHelp(false); + cout << "Options:" << endl; + cout << " -h" << endl; + cout << " Print detailed help screen" << endl; + cout << " -V" << endl; + cout << " Print version information" << endl; + cout << " -H HOSTADDRESS" << endl; + cout << " Host where the Source DS is running" << endl; + cout << " -p" << endl; + cout << " Port where the Source DS is listening. Default is 27015." << endl << endl; + return; + } + cout << "Usage: " << endl << "check_csgo [-hV] -H HOSTADDRESS [-p PORT]" << endl << endl; +} + +int check_upnp(char *hostname, string *serverinfo) +{ + char buffer[MAX_UDP+1]; + struct sockaddr_in si; + struct hostent *host = NULL; + int s; + int timeout = 10; + struct hostent *he; + struct in_addr **addr_list; + + he = gethostbyname(hostname); + if(he == NULL) + { + *serverinfo = "Can't resolve " + string(hostname); + return 3; + } + addr_list = (struct in_addr **) he->h_addr_list; + char *targetIP = inet_ntoa(*addr_list[0]); + + setupSocket(1900,(char*)"239.255.255.250",host,timeout,&si,&s); + memset(buffer,0x00,MAX_UDP+1); + char *discover = (char*) "M-SEARCH * HTTP/1.1\r\nHOST: 239.255.255.250:1900\r\nMAN: \"ssdp:discover\"\r\nMX: 5\r\nST: urn:schemas-upnp-org:device:MediaServer:1\r\n\r\n"; + sendMsg(s,discover,strlen(discover),&si); + while(true) + { + recvMsg(s, buffer, MAX_UDP, &si); + char *sourceIP = inet_ntoa(si.sin_addr); + if(!strcmp(sourceIP,targetIP)) + { + stringstream ss(buffer); + string line; + while(getline(ss,line,'\n')) + { + if(line.length() > strlen("SERVER:")) + { + if (line.substr(0,strlen("SERVER:")) == "SERVER:") + { + *serverinfo = line.substr(0,line.size() - 1); + } + } + } + return 0; + } + + } +} + +int main(int argc, char **argv) +{ + struct itimerval timer; + timer.it_value.tv_sec = 10; + timer.it_value.tv_usec = 0; + timer.it_interval.tv_sec = 0; + timer.it_interval.tv_usec = 0; + setitimer (ITIMER_VIRTUAL, &timer, 0); + + struct sigaction sa; + memset (&sa, 0, sizeof (sa)); + sa.sa_handler = &timer_handler; + sigaction (SIGVTALRM, &sa, 0); + + uint16_t port = 27015; + char *hostname = NULL; + int c; + + while ((c = getopt (argc, argv, "H:p:Vh")) != -1) + { + switch(c) + { + case 'H': + hostname = optarg; + break; + case 'p': + port = (uint16_t) str2int(optarg); + break; + case 'V': + printVersion(); + return 0; + case 'h': + printHelp(true); + return 0; + case '?': + printHelp(false); + return 3; + } + } + + if(hostname == NULL) + { + cout << "No HOSTADDRESS specified. Exiting." << endl; + return 3; + } + + string serverinfo = ""; + int returnCode = check_upnp(hostname,&serverinfo); + + cout << servicename; + switch(returnCode) + { + case 0: + cout << " OK - " << serverinfo << endl ; + break; + + case 2: + cout << " CRITICAL - No response"; + break; + + case 3: + cout << " UNKNOWN - " << serverinfo << endl; + } + + return returnCode; +} diff --git a/check_upnp/check_upnp.h b/check_upnp/check_upnp.h new file mode 100755 index 0000000..2278fa7 --- /dev/null +++ b/check_upnp/check_upnp.h @@ -0,0 +1,25 @@ +#ifndef CHECK_UPNP_H +#define CHECK_UPNP_H + +#include +#include +#include +#include + +#include +#include +#include +#include + +#include + +#include "auxiliar.h" +#include "udp.h" + +#define VERSION "1.0" + +int check_upnp(char *hostname, string *serverinfo); +void printVersion(); +void printHelp(bool longVersion); + +#endif diff --git a/check_upnp/udp.cpp b/check_upnp/udp.cpp new file mode 100644 index 0000000..534d5ba --- /dev/null +++ b/check_upnp/udp.cpp @@ -0,0 +1,39 @@ +#include "udp.h" + +void setupSocket(uint16_t port, char *hostname, struct hostent *host, int timeout, struct sockaddr_in *si, int *s) +{ + if((*s = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP)) == -1) + { + cout << "Couldn't create socket" << endl; + exit(3); + } + struct timeval tv; + tv.tv_sec = timeout; + tv.tv_usec = 0; + if(setsockopt(*s, SOL_SOCKET, SO_RCVTIMEO,&tv,sizeof(tv)) < 0) + { + cout << "Error setting socket timeout" << endl; + exit(3); + } + if(!(host = gethostbyname(hostname))) + { + cout << "Client could not get host address information" << endl; + exit(3); + } + + memset((char *) si, 0, sizeof(*si)); + si->sin_family = AF_INET; + memcpy (&(si->sin_addr), host->h_addr, host->h_length); + si->sin_port = htons(port); +} + +int sendMsg(int s, char *msg, size_t msgLength, struct sockaddr_in *si) +{ + return sendto(s, msg, msgLength, 0,(struct sockaddr*) si, sizeof(*si)); +} + +int recvMsg(int s, char *msg, size_t msgLength, struct sockaddr_in *si) +{ + size_t slen = sizeof(*si); + return recvfrom(s, msg, msgLength, 0, (struct sockaddr *) si, (socklen_t*)&slen); +} diff --git a/check_upnp/udp.h b/check_upnp/udp.h new file mode 100644 index 0000000..bdbe48f --- /dev/null +++ b/check_upnp/udp.h @@ -0,0 +1,22 @@ +#ifndef UDP_H +#define UDP_H + +#include + +#include +#include + +#include +#include +#include +#include + +#define MAX_UDP 65507 + +using namespace std; + +void setupSocket(uint16_t port, char *hostname, struct hostent *host, int timeout, struct sockaddr_in *si, int *s); +int sendMsg(int s, char *msg, size_t msgLength, struct sockaddr_in *si); +int recvMsg(int s, char *msg, size_t msgLength, struct sockaddr_in *si); + +#endif -- libgit2 0.22.2