From 833be39f73bde1e452b4b8adfe3ad0bd36b18a3a Mon Sep 17 00:00:00 2001 From: Tim Niemeyer Date: Mon, 2 Apr 2018 14:10:33 +0200 Subject: [PATCH] rewrite in C --- CMakeLists.txt | 18 +++---- log.cpp | 29 ------------ log.h | 14 +++--- mac.cpp | 14 ------ mac.h | 13 ----- macnockclient.c | 108 ++++++++++++++++++++++++++++++++++++++++++ macnockclient.cpp | 107 ----------------------------------------- macnockclient.h | 19 ++------ macnockserver.c | 118 ++++++++++++++++++++++++++++++++++++++++++++++ macnockserver.cpp | 116 --------------------------------------------- macnockserver.h | 27 +++-------- macstorage.c | 91 +++++++++++++++++++++++++++++++++++ macstorage.h | 10 ++++ main.c | 108 ++++++++++++++++++++++++++++++++++++++++++ main.cpp | 65 ------------------------- nockpackage.cpp | 75 ----------------------------- nockpackage.h | 35 ++++---------- tc.c | 88 ++++++++++++++++++++++++++++++++++ tc.cpp | 79 ------------------------------- tc.h | 26 ++-------- 20 files changed, 562 insertions(+), 598 deletions(-) delete mode 100644 log.cpp delete mode 100644 mac.cpp delete mode 100644 mac.h create mode 100644 macnockclient.c delete mode 100644 macnockclient.cpp create mode 100644 macnockserver.c delete mode 100644 macnockserver.cpp create mode 100644 macstorage.c create mode 100644 macstorage.h create mode 100644 main.c delete mode 100644 main.cpp delete mode 100644 nockpackage.cpp create mode 100644 tc.c delete mode 100644 tc.cpp diff --git a/CMakeLists.txt b/CMakeLists.txt index f287728..b27af8f 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -1,25 +1,21 @@ cmake_minimum_required(VERSION 3.0) -project(macNock C CXX) +project(macNock C) option(MACNOCK_DEBUG "Enable debug messages" OFF) -if(CMAKE_COMPILER_IS_GNUCXX) - add_definitions(-Wall -Wpedantic -Wextra -std=c++11) -endif() +add_definitions(-Wall -Wextra -pedantic) if(MACNOCK_DEBUG) add_definitions(-DDEBUG) endif(MACNOCK_DEBUG) set(MACNOCK_SRC - main.cpp - macnockserver.cpp - macnockclient.cpp - nockpackage.cpp - mac.cpp - tc.cpp - log.cpp + main.c + macnockserver.c + macnockclient.c + tc.c + macstorage.c ) add_executable(macnock ${MACNOCK_SRC}) diff --git a/log.cpp b/log.cpp deleted file mode 100644 index 00eba8d..0000000 --- a/log.cpp +++ /dev/null @@ -1,29 +0,0 @@ -#include "log.h" - -#include -#include - -namespace log { - -std::mutex g_output_mutex; - -#ifdef DEBUG -void debug(const std::string &dbg) -{ - std::lock_guard guard(g_output_mutex); - std::cout << dbg << std::endl; -} -#else -void debug(const std::string &) -{ - -} -#endif - -void error(const std::string &dbg) -{ - std::lock_guard guard(g_output_mutex); - std::cerr << dbg << std::endl; -} - -} // namespace log diff --git a/log.h b/log.h index dce0af9..c73461f 100644 --- a/log.h +++ b/log.h @@ -1,14 +1,12 @@ #ifndef _DEBUG_H #define _DEBUG_H -#include +#ifdef DEBUG +#include -namespace log { - -void debug(const std::string &dbg); - -void error(const std::string &dbg); - -} // namespace log +#define log_debug(...) printf(__VA_ARGS__) +#else +#define log_debug(...) do { } while (0); +#endif #endif // _DEBUG_H diff --git a/mac.cpp b/mac.cpp deleted file mode 100644 index 93ab0cb..0000000 --- a/mac.cpp +++ /dev/null @@ -1,14 +0,0 @@ -#include "mac.h" - -#include -#include - -std::string to_string(const Mac &o) -{ - std::ostringstream stream; - for (Mac::const_iterator it=o.begin(); it!=o.end(); ++it) - { - stream << std::hex << std::setw(2) << std::setfill('0') << static_cast(*it); - } - return stream.str(); -} diff --git a/mac.h b/mac.h deleted file mode 100644 index 4944448..0000000 --- a/mac.h +++ /dev/null @@ -1,13 +0,0 @@ -#ifndef _MAC_H -#define _MAC_H - -#include -#include -#include - -using Mac = std::array; -using MacList = std::list; - -std::string to_string(const Mac &o); - -#endif // _MAC_H diff --git a/macnockclient.c b/macnockclient.c new file mode 100644 index 0000000..0f2ebdc --- /dev/null +++ b/macnockclient.c @@ -0,0 +1,108 @@ +#include "macnockclient.h" +#include "nockpackage.h" +#include "log.h" + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +extern const char *g_hood; +extern const char *g_interface; + +extern const int PORT; +extern const uint8_t VERSION; + +static uint8_t stop; + +void macNockClient_stop() +{ + log_debug("Stopping Client\n"); + stop = 1; +} + +void macNockClient_run() +{ + stop = 0; + + const char host[] = "ff02::1"; + + int fd = socket(AF_INET6, SOCK_DGRAM, IPPROTO_UDP); + if (fd < 0) + { + perror("[c] ERROR: Can't create socket"); + return; + } + + if (setsockopt(fd, SOL_SOCKET, SO_BINDTODEVICE, g_interface, strlen(g_interface)) < 0) + { + perror("[c] WARNING: Can't bind to device"); + } + + struct ifreq ifr; + memset(&ifr, 0, sizeof(ifr)); + strncpy(ifr.ifr_name, g_interface, IFNAMSIZ); + + if (!((ioctl(fd, SIOCGIFFLAGS, &ifr) == 0) && (ioctl(fd, SIOCGIFHWADDR, &ifr) == 0))) + { + perror("[c] ERROR: Can't read MAC"); + close(fd); + return; + } + + struct sockaddr_in6 servaddr; + memset(&servaddr, 0, sizeof(servaddr)); + servaddr.sin6_family = AF_INET6; + servaddr.sin6_port = htons(PORT); + + if (inet_pton(AF_INET6, host, &servaddr.sin6_addr) == 0) + { + perror("[c] ERROR: Can't resolve host"); + close(fd); + return; + } + + const size_t hoodLen = strlen(g_hood)+1; + struct NockPackage *nock = malloc(sizeof(struct NockPackage) + hoodLen); + memcpy(nock->mac, ifr.ifr_hwaddr.sa_data, sizeof(nock->mac)); + nock->version = VERSION; + nock->hoodLen = hoodLen; + strcpy(nock->hood, g_hood); + const size_t len = sizeof(struct NockPackage) + hoodLen; + + while (!stop) + { + log_debug("[c] sending\n"); + + int sent = sendto(fd, nock, len, 0, (struct sockaddr *)&servaddr, sizeof(servaddr)); + if (sent == -1) + { + perror("[c] ERROR: Can't send data"); + } + else if ((size_t)sent != len) + { + perror("[c] ERROR: Can't send all data"); + } + + usleep(1 * 1000 * 1000); // sleep 1 s + } + + free(nock); + + close(fd); + + log_debug("Client closed\n"); + return; +} diff --git a/macnockclient.cpp b/macnockclient.cpp deleted file mode 100644 index be072a0..0000000 --- a/macnockclient.cpp +++ /dev/null @@ -1,107 +0,0 @@ -#include "macnockclient.h" -#include "nockpackage.h" -#include "log.h" - -#include - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include -#include - -macNockClient::macNockClient(const std::string &interface, const std::string &hood) - : m_interface(interface) - , m_hood(hood) -{ - -} - -void macNockClient::stop() -{ - log::debug("Stopping Client"); - m_stop = true; -} - -bool macNockClient::run() -{ - const std::string host{"ff02::1"}; - - m_stop = false; - - int fd = socket(AF_INET6, SOCK_DGRAM, IPPROTO_UDP); - if (fd < 0) - { - log::error(std::string("[c] ERROR: Can't create socket (") + strerror(errno) + ")."); - return false; - } - - if (setsockopt(fd, SOL_SOCKET, SO_BINDTODEVICE, m_interface.c_str(), m_interface.size()) < 0) - { - log::error(std::string("[c] WARNING: Can't bind to device (") + strerror(errno) + ")."); - } - - ifreq ifr; - memset(&ifr, 0, sizeof(ifreq)); - strncpy(ifr.ifr_name, m_interface.c_str(), IFNAMSIZ); - - if (!((ioctl(fd, SIOCGIFFLAGS, &ifr) == 0) && (ioctl(fd, SIOCGIFHWADDR, &ifr) == 0))) - { - log::error(std::string("[c] ERROR: Can't read MAC (") + strerror(errno) + ")."); - return false; - } - - sockaddr_in6 servaddr; - memset(&servaddr, 0, sizeof(sockaddr_in6)); - servaddr.sin6_family = AF_INET6; - servaddr.sin6_port = htons(PORT); - - if (inet_pton(AF_INET6, host.c_str(), &servaddr.sin6_addr) == 0) - { - log::error(std::string("[c] ERROR: Can't resolve host (") + strerror(errno) + ")."); - close(fd); - return false; - } - - const Mac mac{ static_cast(ifr.ifr_hwaddr.sa_data[0]), static_cast(ifr.ifr_hwaddr.sa_data[1]), - static_cast(ifr.ifr_hwaddr.sa_data[2]), static_cast(ifr.ifr_hwaddr.sa_data[3]), - static_cast(ifr.ifr_hwaddr.sa_data[4]), static_cast(ifr.ifr_hwaddr.sa_data[5]), }; - const NockPackage nock{mac, m_hood}; - - while (!m_stop) - { - log::debug("[c] sending"); - uint8_t buf[256]; - size_t len = nock.serialize(buf, 256); - - int sent = sendto(fd, buf, len, 0, reinterpret_cast(&servaddr), sizeof(servaddr)); - if (sent == -1) - { - log::error(std::string("[c] ERROR: Can't send data (") + strerror(errno) + ")."); - } - else if (static_cast(sent) != len) - { - log::error("[c] ERROR: Can't send all data."); - } - - std::this_thread::sleep_for(std::chrono::seconds(1)); - } - - close(fd); - - log::debug("Client closed"); - return true; -} diff --git a/macnockclient.h b/macnockclient.h index f7ca82d..da6269c 100644 --- a/macnockclient.h +++ b/macnockclient.h @@ -1,16 +1,7 @@ -#include +#ifndef _MACNOCKCLIENT_H +#define _MACNOCKCLIENT_H -class macNockClient -{ -public: - macNockClient(const std::string &interface, const std::string &code); - bool run(); - void stop(); +void macNockClient_stop(); +void macNockClient_run(); -private: - -private: - const std::string &m_interface; - const std::string &m_hood; - bool m_stop; -}; +#endif // _MACNOCKCLIENT_H diff --git a/macnockserver.c b/macnockserver.c new file mode 100644 index 0000000..865ba83 --- /dev/null +++ b/macnockserver.c @@ -0,0 +1,118 @@ +#include "macnockserver.h" +#include "macstorage.h" +#include "nockpackage.h" +#include "log.h" +#include "tc.h" + +#include +#include +#include +#include +#include +#include + +#include +#include +#include + +extern const char *g_hood; +extern const char *g_interface; + +extern const int PORT; +extern const uint8_t VERSION; + +static uint8_t stop; +int fd; + +void macNockServer_stop() +{ + log_debug("Stopping Server\n"); + stop = 1; + shutdown(fd, SHUT_RDWR); +} + +void macNockServer_run() +{ + stop = 0; + + tc_start(); + + fd = socket(AF_INET6, SOCK_DGRAM, IPPROTO_UDP); + + if (fd < 0) + { + perror("[s] ERROR: Can't create socket"); + return; + } + + // allow to reuse the port immediately as soon as the service exits. + int sockoptval = 1; + if (setsockopt(fd, SOL_SOCKET, SO_REUSEADDR, &sockoptval, sizeof(int)) != 0) + { + perror("[s] WARNING: Can't set socket options"); + } + + struct sockaddr_in6 my_addr; + memset(&my_addr, 0, sizeof(my_addr)); + my_addr.sin6_family = AF_INET6; + my_addr.sin6_port = htons(PORT); + my_addr.sin6_addr = in6addr_any; + + if (bind(fd, (struct sockaddr *)&my_addr, sizeof(my_addr)) < 0) + { + perror("[s] ERROR: Can't bind to address"); + return; + } + + while (!stop) + { + log_debug("[s] waiting for connection\n"); + + struct sockaddr_in6 client_addr; + socklen_t addrlen = sizeof(client_addr); + + static const size_t BUFSIZE = 2048; + uint8_t buf[BUFSIZE]; + + int recvlen = recvfrom(fd, buf, BUFSIZE, 0, (struct sockaddr *)&client_addr, &addrlen); + + if (recvlen <= 0) + { + continue; + } + + char addrBuf[INET6_ADDRSTRLEN]; + const char *ret = inet_ntop(AF_INET6, &client_addr.sin6_addr, addrBuf, sizeof(addrBuf)); + log_debug("[s] received %d bytes from %s\n", recvlen, ret); + + struct NockPackage *nock = (struct NockPackage *)buf; + nock->hood[nock->hoodLen] = '\0'; + + if (nock->version != VERSION) + { + fprintf(stderr, "Received package with wrong version from %s\n", ret); + continue; + } + + log_debug("The MAC: %2x:%2x:%2x:%2x:%2x:%2x, the Hood: %s\n", + nock->mac[0], nock->mac[1], nock->mac[2], nock->mac[3], nock->mac[4], nock->mac[5], nock->hood); + + if (strcmp(nock->hood, g_hood) == 0) + { + log_debug("[s] allowing %2x:%2x:%2x:%2x:%2x:%2x\n", + nock->mac[0], nock->mac[1], nock->mac[2], nock->mac[3], nock->mac[4], nock->mac[5]); + macStorage_add(nock->mac); + } + else + { + log_debug("[s] wrong hood. Not allowing %2x:%2x:%2x:%2x:%2x:%2x\n", + nock->mac[0], nock->mac[1], nock->mac[2], nock->mac[3], nock->mac[4], nock->mac[5]); + } + } + + close(fd); + tc_stop(); + + log_debug("Server closed\n"); + return; +} diff --git a/macnockserver.cpp b/macnockserver.cpp deleted file mode 100644 index ffc6805..0000000 --- a/macnockserver.cpp +++ /dev/null @@ -1,116 +0,0 @@ -#include "macnockserver.h" -#include "nockpackage.h" -#include "log.h" - -#include -#include -#include -#include -#include -#include -#include -#include - -macNockServer::macNockServer(const std::string &interface, const std::string &hood) - : m_interface(interface) - , m_hood(hood) - , m_stop(false) - , m_tc(interface) -{ - -} - -bool macNockServer::run() -{ - m_sock = socket(AF_INET6, SOCK_DGRAM, IPPROTO_UDP); - - if (m_sock < 0) - { - log::error(std::string("[s] ERROR: Can't create socket (") + strerror(errno) + ")."); - return false; - } - - // allow to reuse the port immediately as soon as the service exits. - int sockoptval = 1; - if (setsockopt(m_sock, SOL_SOCKET, SO_REUSEADDR, &sockoptval, sizeof(int)) != 0) - { - log::error(std::string("[s] WARNING: Can't set socket options (") + strerror(errno) + ")."); - } - - sockaddr_in6 my_addr; - memset(&my_addr, 0, sizeof(sockaddr_in6)); - my_addr.sin6_family = AF_INET6; - my_addr.sin6_port = htons(PORT); - my_addr.sin6_addr = in6addr_any; - - if (bind(m_sock, reinterpret_cast(&my_addr), sizeof(sockaddr_in6)) < 0) - { - log::error(std::string("[s] ERROR: Can't bind to address (") + strerror(errno) + ")"); - return false; - } - - while (!m_stop) - { - log::debug(std::string("[s] waiting on port ") + std::to_string(PORT)); - - sockaddr_in6 client_addr; - socklen_t addrlen = sizeof(client_addr); - - static const size_t BUFSIZE = 2048; - uint8_t buf[BUFSIZE]; - - int recvlen = recvfrom(m_sock, buf, BUFSIZE, 0, reinterpret_cast(&client_addr), &addrlen); - - if (recvlen <= 0) - { - continue; - } - - char addrBuf[INET6_ADDRSTRLEN]; - const char *ret = inet_ntop(AF_INET6, &client_addr.sin6_addr, addrBuf, sizeof(addrBuf)); - log::debug(std::string("[s] received ") + std::to_string(recvlen) + " bytes from " + ret); - - NockPackage nock; - if (nock.deserialize(buf, recvlen)) - { - const std::string mac{to_string(nock.getMac())}; - log::debug(std::string("The MAC: ") + mac + ", the Hood: " + nock.getHood()); - - if (nock.getHood() == m_hood) - { - log::debug(std::string("[s] allowing ") + mac); - MacList::iterator found = std::find(m_filterList.begin(), m_filterList.end(), nock.getMac()); - if (found == m_filterList.end()) - { - m_filterList.push_back(nock.getMac()); - m_tc.allow_mac(mac); - } - } - else - { - log::debug(std::string("[s] not allowing ") + mac + ", wrong hood"); - MacList::iterator found = std::remove(m_filterList.begin(), m_filterList.end(), nock.getMac()); - if (found != m_filterList.end()) - { - m_filterList.erase(found); - m_tc.disallow_mac(mac); - } - } - } - else - { - log::error(std::string("[s] can't deserialize message \"") + std::string(buf, buf+recvlen) + "\""); - } - } - - close(m_sock); - log::debug("Server closed"); - return true; -} - -void macNockServer::stop() -{ - log::debug("Stopping Server"); - m_stop = true; - shutdown(m_sock, SHUT_RDWR); -} diff --git a/macnockserver.h b/macnockserver.h index 40b6951..2dc277c 100644 --- a/macnockserver.h +++ b/macnockserver.h @@ -1,24 +1,9 @@ +#ifndef _MACNOCKSERVER_H +#define _MACNOCKSERVER_H + #include "tc.h" -#include "mac.h" -#include -#include +void macNockServer_stop(); +void macNockServer_run(); -class macNockServer -{ -public: - macNockServer(const std::string &interface, const std::string &hood); - bool run(); - void stop(); - -private: - void sendData(const int socket, const std::string &data) const; - -private: - const std::string &m_interface; - const std::string &m_hood; - bool m_stop; - int m_sock; - tc m_tc; - MacList m_filterList; -}; +#endif // _MACNOCKSERVER_H diff --git a/macstorage.c b/macstorage.c new file mode 100644 index 0000000..e88e460 --- /dev/null +++ b/macstorage.c @@ -0,0 +1,91 @@ +#include "macstorage.h" +#include "log.h" +#include "tc.h" + +#include +#include +#include +#include +#include + +static uint8_t stop; + +#define MAXENTRIES 30 + +struct Entry +{ + uint8_t mac[6]; + time_t timestamp; +} storage[MAXENTRIES]; + +size_t count = 0; + +pthread_mutex_t mux; + +void _addEntry(uint8_t mac[6]) +{ + for (size_t i=0; i + +void macStorage_add(uint8_t mac[]); +void macStorage_stop(); +void macStorage_run(); + +#endif // _MACSTORAGE_H diff --git a/main.c b/main.c new file mode 100644 index 0000000..f37ba8b --- /dev/null +++ b/main.c @@ -0,0 +1,108 @@ +#include "macnockserver.h" +#include "macnockclient.h" +#include "macstorage.h" +#include "log.h" + +#include +#include +#include +#include +#include + +const int PORT = 2342; +const uint8_t VERSION = 1; + +const char *g_interface; +const char *g_hood; + +void sigHandler(int sig) +{ + (void)sig; + macNockServer_stop(); + macNockClient_stop(); + macStorage_stop(); +} + +void* serverRoutine(void *arg) +{ + macNockServer_run(); + return arg; +} + +void* clientRoutine(void *arg) +{ + macNockClient_run(); + return arg; +} + +void* storageRoutine(void *arg) +{ + macStorage_run(); + return arg; +} + +int main(int argc, char *argv[]) +{ + if (argc < 3) + { + printf("Send and listen for nock requests\n"); + printf("\n"); + printf("%s interface code command\n", argv[0]); + printf("Example:\n"); + printf("%s eth0.3 \"FuerthV2\"\n", argv[0]); + return -1; + } + + g_interface = argv[1]; + g_hood = argv[2]; + + //log_debug("Running for hood %s (%s) on interface %s (%s)\n", g_hood, argv[1], g_interface, argv[2]); + + signal(SIGINT, &sigHandler); + signal(SIGTERM, &sigHandler); + + pthread_t serverThread; + pthread_t clientThread; + pthread_t storageThread; + + if (pthread_create(&serverThread, NULL, serverRoutine, NULL)) + { + fprintf(stderr, "Error creating thread\n"); + return 1; + } + + if (pthread_create(&clientThread, NULL, clientRoutine, NULL)) + { + fprintf(stderr, "Error creating thread\n"); + return 1; + } + + if (pthread_create(&storageThread, NULL, storageRoutine, NULL)) + { + fprintf(stderr, "Error creating thread\n"); + return 1; + } + + if (pthread_join(serverThread, NULL)) + { + fprintf(stderr, "Error joining thread\n"); + return 2; + } + + if (pthread_join(clientThread, NULL)) + { + fprintf(stderr, "Error joining thread\n"); + return 2; + } + + if (pthread_join(storageThread, NULL)) + { + fprintf(stderr, "Error joining thread\n"); + return 2; + } + + signal(SIGINT, SIG_DFL); + signal(SIGTERM, SIG_DFL); + + return 0; +} diff --git a/main.cpp b/main.cpp deleted file mode 100644 index e95e078..0000000 --- a/main.cpp +++ /dev/null @@ -1,65 +0,0 @@ -#include "macnockserver.h" -#include "macnockclient.h" -#include -#include -#include -#include -#include -#include - -macNockServer *server = nullptr; -macNockClient *client = nullptr; - -void sigHandler(int) -{ - if (server) - { - server->stop(); - } - if (client) - { - client->stop(); - } -} - -int main(int argc, char *argv[]) -{ - if (argc < 3) - { - std::cout << "Send and listen for nock requests" << std::endl; - std::cout << std::endl; - std::cout << argv[0] << " interface code command" << std::endl; - std::cout << "Example:" << std::endl; - std::cout << argv[0] << " eth0.3 \"FuerthV2\"" << std::endl; - return -1; - } - - const std::string interface{argv[1]}; - const std::string hood{argv[2]}; - - server = new macNockServer{interface, hood}; - client = new macNockClient{interface, hood}; - - signal(SIGINT, &sigHandler); - signal(SIGTERM, &sigHandler); - - std::thread serverThread{[](){server->run();}}; - - std::this_thread::sleep_for(std::chrono::milliseconds(10)); - - std::thread clientThread{[](){client->run();}}; - - serverThread.join(); - clientThread.join(); - - signal(SIGINT, SIG_DFL); - signal(SIGTERM, SIG_DFL); - - delete client; - client = nullptr; - - delete server; - server = nullptr; - - return 0; -} diff --git a/nockpackage.cpp b/nockpackage.cpp deleted file mode 100644 index 5dd9160..0000000 --- a/nockpackage.cpp +++ /dev/null @@ -1,75 +0,0 @@ -#include "nockpackage.h" - -#include - -NockPackage::NockPackage() -{ - -} - -NockPackage::NockPackage(const Mac &sourceMac, const Hood &hoodName) - : m_sourceMac(sourceMac) - , m_hoodName(hoodName) -{ - -} - -size_t NockPackage::serialize(uint8_t *buf, size_t maxlen) const -{ - uint8_t *target = buf; - if (maxlen < (m_sourceMac.size() + 1)) - return 0; - - *target = VERSION; - target++; - - for (Mac::const_iterator it=m_sourceMac.begin(); it!=m_sourceMac.end(); ++it) - { - *target = *it; - target++; - } - - for (Hood::const_iterator it=m_hoodName.begin(); it!=m_hoodName.end(); ++it) - { - *target = *it; - target++; - } - - return target-buf; -} - -bool NockPackage::deserialize(const uint8_t *buf, size_t len) -{ - const uint8_t *source = buf; - - if (len < (m_sourceMac.size() + 1)) - { - return false; - } - - if (*source != VERSION) - { - return false; - } - source++; - - for (Mac::iterator it=m_sourceMac.begin(); it!=m_sourceMac.end(); ++it) - { - *it = *source; - source++; - } - - m_hoodName = std::string(source, buf+len); - - return true; -} - -Mac NockPackage::getMac() const -{ - return m_sourceMac; -} - -std::string NockPackage::getHood() const -{ - return m_hoodName; -} diff --git a/nockpackage.h b/nockpackage.h index 85bc735..9d0a8db 100644 --- a/nockpackage.h +++ b/nockpackage.h @@ -1,33 +1,18 @@ #ifndef _PROTOCOL_H #define _PROTOCOL_H -#include "mac.h" +#include -#include - -static const int PORT{2342}; -static const int8_t VERSION{1}; - -class NockPackage +struct NockPackage { -public: - using Hood = std::string; - - NockPackage(); - - NockPackage(const Mac &sourceMac, const Hood &hoodName); - - size_t serialize(uint8_t *buf, size_t maxlen) const; - - bool deserialize(const uint8_t *buf, size_t len); - - Mac getMac() const; - - std::string getHood() const; - -private: - Mac m_sourceMac; - Hood m_hoodName; + uint8_t version; + uint8_t mac[6]; + uint8_t hoodLen; + char hood[]; }; +//size_t NockPackage_serialize(uint8_t *buf, size_t maxlen, const NockPackage *p); + +//uint8_t NockPackage_deserialize(NockPackage *p, const uint8_t *buf, size_t len); + #endif // _PROTOCOL_H diff --git a/tc.c b/tc.c new file mode 100644 index 0000000..c3a8004 --- /dev/null +++ b/tc.c @@ -0,0 +1,88 @@ +#include "tc.h" +#include "log.h" + +#include +#include + +/* + * if=eth0 + * + * # qdisc anlegen: + * tc qdisc add dev $if ingress + * + * # alles sperren: + * tc filter add dev $if protocol all parent ffff: prio 65535 basic match "u32(u16 0x4305 0xffff at -2)" flowid :1 action drop + * + * # eine mac frei schalten: + * tc filter add dev $if protocol all parent ffff: prio 99 basic match "u32(u32 0xf81a67a5 0xffffffff at -8)" and "u32(u16 0xf4cb 0xffff at -4)" flowid :1 action pass + * + * # qdisc anzeigen + * tc qdisc + * + * # qdisc löschen + * tc qdisc del dev $if ingress + * + * # filter anzeigen + * tc filter show dev $if ingress + */ + +extern const char *g_interface; + +void tc_add_qdisc_ingress() +{ + char cmd[2048]; + snprintf(cmd, 2048, "/sbin/tc qdisc add dev %s ingress", g_interface); + log_debug("CMD: %s\n", cmd); + system(cmd); +} + +void tc_del_qdisc_ingress() +{ + char cmd[2048]; + snprintf(cmd, 2048, "/sbin/tc qdisc del dev %s ingress", g_interface); + log_debug("CMD: %s\n", cmd); + system(cmd); +} + +void tc_block_all() +{ + char cmd[2048]; + snprintf(cmd, 2048, "/sbin/tc filter add dev %s protocol all parent ffff: prio 65535 basic match \"u32(u16 0x4305 0xffff at -2)\" flowid :1 action drop", g_interface); + log_debug("CMD: %s\n", cmd); + system(cmd); +} + +void tc_allow_mac(const uint8_t mac[]) +{ + char cmd[2048]; + snprintf(cmd, 2048, "/sbin/tc filter add dev %s protocol all parent ffff: prio 99 " + "basic match \"u32(u32 0x%2x%2x%2x%2x 0xffffffff at -8)\" " + "and \"u32(u16 0x%2x%2x 0xffff at -4)\" flowid :1 action pass", + g_interface, mac[0], mac[1], mac[2], mac[3], mac[4], mac[5]); + log_debug("CMD: %s\n", cmd); + system(cmd); +} + +void tc_disallow_mac(const uint8_t mac[]) +{ + char cmd[2048]; + snprintf(cmd, 2048, "/sbin/tc filter delete dev %s protocol all parent ffff: prio 99 " + "basic match \"u32(u32 0x%2x%2x%2x%2x 0xffffffff at -8)\" " + "and \"u32(u16 0x%2x%2x 0xffff at -4)\" flowid :1 action pass", + g_interface, mac[0], mac[1], mac[2], mac[3], mac[4], mac[5]); + log_debug("CMD: %s\n", cmd); + system(cmd); +} + +void tc_start() +{ + tc_del_qdisc_ingress(); // in case a old session is sill there + + tc_add_qdisc_ingress(); + tc_block_all(); +} + +void tc_stop() +{ + tc_del_qdisc_ingress(); +} diff --git a/tc.cpp b/tc.cpp deleted file mode 100644 index ee02b90..0000000 --- a/tc.cpp +++ /dev/null @@ -1,79 +0,0 @@ -#include "tc.h" -#include "log.h" - -#include - -/* - * if=eth0 - * - * # qdisc anlegen: - * tc qdisc add dev $if ingress - * - * # alles sperren: - * tc filter add dev $if protocol all parent ffff: prio 65535 basic match "u32(u16 0x4305 0xffff at -2)" flowid :1 action drop - * - * # eine mac frei schalten: - * tc filter add dev $if protocol all parent ffff: prio 99 basic match "u32(u32 0xf81a67a5 0xffffffff at -8)" and "u32(u16 0xf4cb 0xffff at -4)" flowid :1 action pass - * - * # qdisc anzeigen - * tc qdisc - * - * # qdisc löschen - * tc qdisc del dev $if ingress - * - * # filter anzeigen - * tc filter show dev $if ingress - */ - -tc::tc(const std::string &interface) - : m_interface(interface) -{ - del_qdisc_ingress(); // in case a old session is sill there - - add_qdisc_ingress(); - block_all(); -} - -tc::~tc() -{ - del_qdisc_ingress(); -} - -void tc::add_qdisc_ingress() -{ - const std::string cmd{"/sbin/tc qdisc add dev "+m_interface+" ingress"}; - log::debug(std::string("CMD: ") + cmd); - std::system(cmd.c_str()); -} - -void tc::del_qdisc_ingress() -{ - const std::string cmd{"/sbin/tc qdisc del dev "+m_interface+" ingress"}; - log::debug(std::string("CMD: ") + cmd); - std::system(cmd.c_str()); -} - -void tc::block_all() -{ - const std::string cmd{"/sbin/tc filter add dev "+m_interface+" protocol all parent ffff: prio 65535 basic match \"u32(u16 0x4305 0xffff at -2)\" flowid :1 action drop"}; - log::debug(std::string("CMD: ") + cmd); - std::system(cmd.c_str()); -} - -void tc::allow_mac(const std::string &mac) -{ - const std::string cmd{"/sbin/tc filter add dev "+m_interface+" protocol all parent ffff: prio 99 " - "basic match \"u32(u32 0x"+mac.substr(0, 8)+" 0xffffffff at -8)\" " - "and \"u32(u16 0x"+mac.substr(8,10)+" 0xffff at -4)\" flowid :1 action pass"}; - log::debug(std::string("CMD: ") + cmd); - std::system(cmd.c_str()); -} - -void tc::disallow_mac(const std::string &mac) -{ - const std::string cmd{"/sbin/tc filter delete dev "+m_interface+" protocol all parent ffff: prio 99 " - "basic match \"u32(u32 0x"+mac.substr(0, 8)+" 0xffffffff at -8)\" " - "and \"u32(u16 0x"+mac.substr(8,10)+" 0xffff at -4)\" flowid :1 action pass"}; - log::debug(std::string("CMD: ") + cmd); - std::system(cmd.c_str()); -} diff --git a/tc.h b/tc.h index e259961..f6088be 100644 --- a/tc.h +++ b/tc.h @@ -1,30 +1,14 @@ #ifndef _TC_H #define _TC_H -#include +#include -class tc -{ -public: - explicit tc(const std::string &interface); +void tc_start(); - ~tc(); +void tc_stop(); - void add_qdisc_ingress(); +void tc_allow_mac(const uint8_t mac[]); - void del_qdisc_ingress(); - - void block_all(); - - void allow_mac(const std::string &mac); - - void disallow_mac(const std::string &mac); - -private: - tc(const tc&); - tc(); - - const std::string m_interface; -}; +void tc_disallow_mac(const uint8_t mac[]); #endif // _TC_H