From af77f68cd630995b069b804183d798b94f18e910 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Nico=20Sch=C3=BCmann?= Date: Wed, 10 Dec 2014 00:14:42 +0100 Subject: [PATCH] Add some more checks --- .../externalscripts/batman_originators | 2 + .../externalscripts/radvd_adv_count | 2 + .../zabbix_server/batman_originators.sh | 2 + .../compile_to_radvd_adv_count.cpp | 191 ++++++++++++++++++ sudoers.d/21_zabbix_server | 2 + 5 files changed, 199 insertions(+) create mode 100644 server_instance/externalscripts/batman_originators create mode 100644 server_instance/externalscripts/radvd_adv_count create mode 100644 server_instance/zabbix_server/batman_originators.sh create mode 100644 server_instance/zabbix_server/compile_to_radvd_adv_count.cpp create mode 100644 sudoers.d/21_zabbix_server diff --git a/server_instance/externalscripts/batman_originators b/server_instance/externalscripts/batman_originators new file mode 100644 index 0000000..9a90006 --- /dev/null +++ b/server_instance/externalscripts/batman_originators @@ -0,0 +1,2 @@ +#!/bin/sh +/usr/bin/sudo /opt/bin/zabbix_server/batman_originators.sh diff --git a/server_instance/externalscripts/radvd_adv_count b/server_instance/externalscripts/radvd_adv_count new file mode 100644 index 0000000..31bf9dd --- /dev/null +++ b/server_instance/externalscripts/radvd_adv_count @@ -0,0 +1,2 @@ +#!/bin/sh +/usr/bin/sudo /opt/bin/zabbix_server/radvd_adv_count diff --git a/server_instance/zabbix_server/batman_originators.sh b/server_instance/zabbix_server/batman_originators.sh new file mode 100644 index 0000000..744ba44 --- /dev/null +++ b/server_instance/zabbix_server/batman_originators.sh @@ -0,0 +1,2 @@ +#!/bin/bash +batctl tg | cut -d")" -f2 | cut -d" " -f3 | grep -v "^$" | sort | uniq | wc -l diff --git a/server_instance/zabbix_server/compile_to_radvd_adv_count.cpp b/server_instance/zabbix_server/compile_to_radvd_adv_count.cpp new file mode 100644 index 0000000..142bfe1 --- /dev/null +++ b/server_instance/zabbix_server/compile_to_radvd_adv_count.cpp @@ -0,0 +1,191 @@ +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#define MAX_GW_AGE 300 +#define SOCKET "/tmp/radvdump_gateway_count.sock" +int stop = 0; +int radvdFD = 0; +std::map routerLastSeenMap; + +void runRadvd() { + if (radvdFD != 0) { + close(radvdFD); + } + + int fd[2]; + pipe(fd); + + int pid = fork(); + if (pid == 0) { + close(fd[0]); + dup2(fd[1], 1); + execlp("radvdump", "radvdump", NULL); + } else if (pid < 0) { + // error + } else { + close(fd[1]); + radvdFD = fd[0]; + } +} + +int openConnection() { + int s, t, len; + struct sockaddr_un remote; + char str[100]; + + if ((s = socket(AF_UNIX, SOCK_STREAM, 0)) == -1) { + return -1; + } + remote.sun_family = AF_UNIX; + strcpy(remote.sun_path, SOCKET); + len = strlen(remote.sun_path) + sizeof(remote.sun_family); + + if (connect(s, (struct sockaddr *)&remote, len) == -1) { + return -1; + } else { + return s; + } +} + +void updateRouter(const std::string &routerString) { + routerLastSeenMap.insert(std::make_pair(routerString, time(NULL))); +} + +void parseBlock(const std::string &string) { + std::stringstream ss(string); + std::string line; + + while (std::getline(ss, line, '\n')) { + size_t pos; + std::string needle("based on Router Advertisement from"); + if ((pos = line.find(needle)) != std::string::npos) { + std::string routerString = line.substr(pos + needle.size() + 1); + updateRouter(routerString); + } + } +} + +uint64_t countRouters() { + std::list timedOut; + uint64_t count = 0; + time_t now = time(NULL); + for (std::map::iterator it = routerLastSeenMap.begin(); it != routerLastSeenMap.end(); ++it) { + if (now - it->second < MAX_GW_AGE) { + count++; + } else { + timedOut.push_back(it->first); + } + } + + for (std::list::iterator it = timedOut.begin(); it != timedOut.end(); ++it) { + routerLastSeenMap.erase(*it); + } + return count; +} + +int createSocket() { + int create_socket; + if((create_socket = socket(AF_LOCAL, SOCK_STREAM, 0)) < 0) { + perror("socket"); + return -1; + } + + unlink(SOCKET); + + struct sockaddr_un address; + socklen_t addrlen; + address.sun_family = AF_UNIX; + strcpy(address.sun_path, SOCKET); + addrlen = sizeof(address); + + if(bind(create_socket, (struct sockaddr *)&address, addrlen) != 0) { + perror("bind"); + return -1; + } + listen(create_socket, 5); + chmod(SOCKET, 0666); + + return create_socket; +} + +void handleClient(int socket) { + struct sockaddr_un address; + socklen_t addrlen; + int client = accept(socket, (struct sockaddr *)&address, &addrlen); + if(client >= 0) { + std::stringstream ss(""); + ss << countRouters() << "\n"; + write(client, ss.str().c_str(), ss.str().size()); + close(client); + } +} + + +void serverMode() { + int socket = createSocket(); + runRadvd(); + while (!stop) { + static fd_set fdSet; + FD_ZERO(&fdSet); + //FD_SET(0, &fdSet); + FD_SET(socket, &fdSet); + FD_SET(radvdFD, &fdSet); + + int maxFd = radvdFD; + + int res = select(maxFd + 1, &fdSet, NULL, NULL, NULL); + if (res == -1) + continue; + + if (FD_ISSET(socket, &fdSet)) { + handleClient(socket); + } + + if (FD_ISSET(radvdFD, &fdSet)) { + char buf[1024]; + int n = read(radvdFD, buf, 1024); + if (n > 0) { + parseBlock(std::string(buf, n)); + } + } + + if (FD_ISSET(0, &fdSet)) { + char buf[16]; + int n = read(0, buf, 16); + std::cout << countRouters() << std::endl; + } + } +} + +int main(void) { + + int clientFd = openConnection(); + if (clientFd == -1) { + int pid = fork(); + if (pid == 0) + serverMode(); + sleep(10); + clientFd = openConnection(); + if (clientFd == -1) { + std::cout << "FAIL." << std::endl; + } + } + + char buf[128]; + size_t n = read(clientFd, buf, 128); + write(1, buf, n); + + return 0; +} diff --git a/sudoers.d/21_zabbix_server b/sudoers.d/21_zabbix_server new file mode 100644 index 0000000..f6010e5 --- /dev/null +++ b/sudoers.d/21_zabbix_server @@ -0,0 +1,2 @@ +zabbix ALL= NOPASSWD: /opt/bin/zabbix_server/batman_originators.sh +zabbix ALL= NOPASSWD: /opt/bin/zabbix_server/radvd_adv_count