X-Git-Url: https://git.stg.codes/stg.git/blobdiff_plain/4271ab433cd55bbd2612292bcf39e4dc3d7274f1..0907aa4037b12b6b88ee24495d4577a064d4f8db:/stargazer/plugins/capture/cap_nf/cap_nf.cpp diff --git a/stargazer/plugins/capture/cap_nf/cap_nf.cpp b/stargazer/plugins/capture/cap_nf/cap_nf.cpp deleted file mode 100644 index 817ed715..00000000 --- a/stargazer/plugins/capture/cap_nf/cap_nf.cpp +++ /dev/null @@ -1,441 +0,0 @@ -/* - * 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - */ - -/* -Date: 16.05.2008 -*/ - -/* -* Author : Maxim Mamontov -*/ - -/* -$Revision: 1.11 $ -$Date: 2010/09/10 06:41:06 $ -$Author: faust $ -*/ - -#include "cap_nf.h" - -#include "stg/common.h" -#include "stg/raw_ip_packet.h" -#include "stg/traffcounter.h" - -#include - -#include -#include -#include - -#include -#include -#include -#include - -namespace -{ - -struct NF_HEADER { - uint16_t version; // Protocol version - uint16_t count; // Flows count - uint32_t uptime; // System uptime - uint32_t timestamp; // UNIX timestamp - uint32_t nsecs; // Residual nanoseconds - uint32_t flowSeq; // Sequence counter - uint8_t eType; // Engine type - uint8_t eID; // Engine ID - uint16_t sInterval; // Sampling mode and interval -}; - -struct NF_DATA { - uint32_t srcAddr; // Flow source address - uint32_t dstAddr; // Flow destination address - uint32_t nextHop; // IP addres on next hop router - uint16_t inSNMP; // SNMP index of input iface - uint16_t outSNMP; // SNMP index of output iface - uint32_t packets; // Packets in flow - uint32_t octets; // Total number of bytes in flow - uint32_t timeStart; // Uptime on first packet in flow - uint32_t timeFinish;// Uptime on last packet in flow - uint16_t srcPort; // Flow source port - uint16_t dstPort; // Flow destination port - uint8_t pad1; // 1-byte padding - uint8_t TCPFlags; // Cumulative OR of TCP flags - uint8_t proto; // IP protocol type (tcp, udp, etc.) - uint8_t tos; // IP Type of Service (ToS) - uint16_t srcAS; // Source BGP autonomous system number - uint16_t dstAS; // Destination BGP autonomus system number - uint8_t srcMask; // Source address mask in "slash" notation - uint8_t dstMask; // Destination address mask in "slash" notation - uint16_t pad2; // 2-byte padding -}; - -#define BUF_SIZE (sizeof(NF_HEADER) + 30 * sizeof(NF_DATA)) - -} - -extern "C" STG::Plugin* GetPlugin() -{ - static NF_CAP plugin; - return &plugin; -} - -NF_CAP::NF_CAP() - : traffCnt(NULL), - runningTCP(false), - runningUDP(false), - stoppedTCP(true), - stoppedUDP(true), - portT(0), - portU(0), - sockTCP(-1), - sockUDP(-1), - logger(STG::PluginLogger::get("cap_nf")) -{ -} - -int NF_CAP::ParseSettings() -{ -std::vector::iterator it; -for (it = settings.moduleParams.begin(); it != settings.moduleParams.end(); ++it) - { - if (it->param == "TCPPort" && !it->value.empty()) - { - if (str2x(it->value[0], portT)) - { - errorStr = "Invalid TCPPort value"; - printfd(__FILE__, "Error: Invalid TCPPort value\n"); - return -1; - } - continue; - } - if (it->param == "UDPPort" && !it->value.empty()) - { - if (str2x(it->value[0], portU)) - { - errorStr = "Invalid UDPPort value"; - printfd(__FILE__, "Error: Invalid UDPPort value\n"); - return -1; - } - continue; - } - printfd(__FILE__, "'%s' is not a valid module param\n", it->param.c_str()); - } -return 0; -} - -int NF_CAP::Start() -{ -if (portU > 0) - { - if (OpenUDP()) - { - return -1; - } - runningUDP = true; - if (pthread_create(&tidUDP, NULL, RunUDP, this)) - { - runningUDP = false; - CloseUDP(); - errorStr = "Cannot create UDP thread"; - logger("Cannot create UDP thread."); - printfd(__FILE__, "Error: Cannot create UDP thread\n"); - return -1; - } - } -if (portT > 0) - { - if (OpenTCP()) - { - return -1; - } - runningTCP = true; - if (pthread_create(&tidTCP, NULL, RunTCP, this)) - { - runningTCP = false; - CloseTCP(); - logger("Cannot create TCP thread."); - errorStr = "Cannot create TCP thread"; - printfd(__FILE__, "Error: Cannot create TCP thread\n"); - return -1; - } - } -return 0; -} - -int NF_CAP::Stop() -{ -runningTCP = runningUDP = false; -if (portU && !stoppedUDP) - { - CloseUDP(); - for (int i = 0; i < 25 && !stoppedUDP; ++i) - { - struct timespec ts = {0, 200000000}; - nanosleep(&ts, NULL); - } - if (stoppedUDP) - { - pthread_join(tidUDP, NULL); - } - else - { - if (pthread_kill(tidUDP, SIGUSR1)) - { - errorStr = "Error sending signal to UDP thread"; - logger("Error sending sugnal to UDP thread."); - printfd(__FILE__, "Error: Error sending signal to UDP thread\n"); - return -1; - } - printfd(__FILE__, "UDP thread NOT stopped\n"); - logger("Cannot stop UDP thread."); - } - } -if (portT && !stoppedTCP) - { - CloseTCP(); - for (int i = 0; i < 25 && !stoppedTCP; ++i) - { - struct timespec ts = {0, 200000000}; - nanosleep(&ts, NULL); - } - if (stoppedTCP) - { - pthread_join(tidTCP, NULL); - } - else - { - if (pthread_kill(tidTCP, SIGUSR1)) - { - errorStr = "Error sending signal to TCP thread"; - logger("Error sending signal to TCP thread."); - printfd(__FILE__, "Error: Error sending signal to TCP thread\n"); - return -1; - } - printfd(__FILE__, "TCP thread NOT stopped\n"); - logger("Cannot stop TCP thread."); - } - } -return 0; -} - -bool NF_CAP::OpenUDP() -{ -struct sockaddr_in sin; -sockUDP = socket(PF_INET, SOCK_DGRAM, 0); -if (sockUDP <= 0) - { - errorStr = "Error opening UDP socket"; - logger("Cannot create UDP socket: %s", strerror(errno)); - printfd(__FILE__, "Error: Error opening UDP socket\n"); - return true; - } -sin.sin_family = AF_INET; -sin.sin_port = htons(portU); -sin.sin_addr.s_addr = inet_addr("0.0.0.0"); -if (bind(sockUDP, (struct sockaddr *)&sin, sizeof(sin))) - { - errorStr = "Error binding UDP socket"; - logger("Cannot bind UDP socket: %s", strerror(errno)); - printfd(__FILE__, "Error: Error binding UDP socket\n"); - return true; - } -return false; -} - -bool NF_CAP::OpenTCP() -{ -struct sockaddr_in sin; -sockTCP = socket(PF_INET, SOCK_STREAM, 0); -if (sockTCP <= 0) - { - errorStr = "Error opening TCP socket"; - logger("Cannot create TCP socket: %s", strerror(errno)); - printfd(__FILE__, "Error: Error opening TCP socket\n"); - return true; - } -sin.sin_family = AF_INET; -sin.sin_port = htons(portT); -sin.sin_addr.s_addr = inet_addr("0.0.0.0"); -if (bind(sockTCP, (struct sockaddr *)&sin, sizeof(sin))) - { - errorStr = "Error binding TCP socket"; - logger("Cannot bind TCP socket: %s", strerror(errno)); - printfd(__FILE__, "Error: Error binding TCP socket\n"); - return true; - } -if (listen(sockTCP, 1)) - { - errorStr = "Error listening on TCP socket"; - logger("Cannot listen on TCP socket: %s", strerror(errno)); - printfd(__FILE__, "Error: Error listening TCP socket\n"); - return true; - } -return false; -} - -void * NF_CAP::RunUDP(void * c) -{ -sigset_t signalSet; -sigfillset(&signalSet); -pthread_sigmask(SIG_BLOCK, &signalSet, NULL); - -NF_CAP * cap = static_cast(c); -cap->stoppedUDP = false; -while (cap->runningUDP) - { - if (!WaitPackets(cap->sockUDP)) - { - continue; - } - - // Data - struct sockaddr_in sin; - socklen_t slen = sizeof(sin); - uint8_t buf[BUF_SIZE]; - ssize_t res = recvfrom(cap->sockUDP, buf, BUF_SIZE, 0, reinterpret_cast(&sin), &slen); - if (!cap->runningUDP) - break; - - if (res < 0) - { - cap->logger("recvfrom error: %s", strerror(errno)); - continue; - } - - if (res == 0) // EOF - { - continue; - } - - if (res < 24) - { - if (errno != EINTR) - { - cap->errorStr = "Invalid data received"; - printfd(__FILE__, "Error: Invalid data received through UDP\n"); - } - continue; - } - - cap->ParseBuffer(buf, res); - } -cap->stoppedUDP = true; -return NULL; -} - -void * NF_CAP::RunTCP(void * c) -{ -sigset_t signalSet; -sigfillset(&signalSet); -pthread_sigmask(SIG_BLOCK, &signalSet, NULL); - -NF_CAP * cap = static_cast(c); -cap->stoppedTCP = false; -while (cap->runningTCP) - { - if (!WaitPackets(cap->sockTCP)) - { - continue; - } - - // Data - struct sockaddr_in sin; - socklen_t slen = sizeof(sin); - int sd = accept(cap->sockTCP, reinterpret_cast(&sin), &slen); - if (!cap->runningTCP) - break; - - if (sd <= 0) - { - if (sd < 0) - cap->logger("accept error: %s", strerror(errno)); - continue; - } - - if (!WaitPackets(sd)) - { - close(sd); - continue; - } - - uint8_t buf[BUF_SIZE]; - ssize_t res = recv(sd, buf, BUF_SIZE, MSG_WAITALL); - - if (res < 0) - cap->logger("recv error: %s", strerror(errno)); - - close(sd); - - if (!cap->runningTCP) - break; - - if (res == 0) // EOF - { - continue; - } - - // Wrong logic! - // Need to check actual data length and wait all data to receive - if (res < 24) - { - continue; - } - - cap->ParseBuffer(buf, res); - } -cap->stoppedTCP = true; -return NULL; -} - -void NF_CAP::ParseBuffer(uint8_t * buf, ssize_t size) -{ -STG::RawPacket ip; -NF_HEADER * hdr = reinterpret_cast(buf); -if (htons(hdr->version) != 5) - { - return; - } - -int packets = htons(hdr->count); - -if (packets < 0 || packets > 30) - { - return; - } - -if (24 + 48 * packets != size) - { - // See 'wrong logic' upper - return; - } - -for (int i = 0; i < packets; ++i) - { - NF_DATA * data = reinterpret_cast(buf + 24 + i * 48); - - ip.rawPacket.header.ipHeader.ip_v = 4; - ip.rawPacket.header.ipHeader.ip_hl = 5; - ip.rawPacket.header.ipHeader.ip_p = data->proto; - ip.dataLen = ntohl(data->octets); - ip.rawPacket.header.ipHeader.ip_src.s_addr = data->srcAddr; - ip.rawPacket.header.ipHeader.ip_dst.s_addr = data->dstAddr; - ip.rawPacket.header.sPort = data->srcPort; - ip.rawPacket.header.dPort = data->dstPort; - - traffCnt->process(ip); - } -}