/*************************************************************************** * Copyright (C) 03/2005 by Olaf Rempel * * razzor@kopf-tisch.de * * * * 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. * ***************************************************************************/ #include #include #include #include #include #include #include #include #include #include #include "list.h" #include "netpkt.h" #include "configfile.h" #include "hlswmaster.h" LIST_HEAD(send_queue); static int scan_sock; /** * pkt_queue() * packt ein paket in die sender queue * @param struct net_pkt *pkt */ void pkt_queue(struct net_pkt *pkt) { list_add_tail(&pkt->list, &send_queue); } /** * scan_transmit() * triggert den scan der plugins * arbeitet die sender queue ab * * TODO: ratelimiting */ void scan_transmit(void) { struct net_pkt *pkt, *tmp; int interval; interval = config_get_int("global", "scan_interval", 30); log_print("starting tx scan thread (%ds interval)", interval); while (1) { plugins_scan(); list_for_each_entry_safe(pkt, tmp, &send_queue, list) { if (sendto(scan_sock, pkt->buf, pkt->size, 0, (struct sockaddr *)&pkt->addr, sizeof(pkt->addr)) < 0) log_print("scan_transmit(): sendto()"); list_del(&pkt->list); free(pkt); usleep(10000); } sleep(interval); } } /** * scan_receive() * wartet auf serverantworten und uebergibt die pakete den * plugins zur auswertung */ void scan_receive(void) { struct net_pkt *pkt; fd_set fdsel, fdcpy; int recvsize, i; log_print("starting rx scan thread"); FD_ZERO(&fdsel); FD_SET(scan_sock, &fdsel); while (1) { memcpy(&fdcpy, &fdsel, sizeof(fdsel)); select(FD_SETSIZE, &fdcpy, NULL, NULL, NULL); ioctl(scan_sock, FIONREAD, &recvsize); if (recvsize <= 0) { log_print("scan_receive(): drop short packet"); continue; } if (!(pkt = malloc(sizeof(struct net_pkt) + recvsize))) { log_print("scan_receive(): malloc()"); continue; } i = sizeof(struct sockaddr_in); pkt->size = recvfrom(scan_sock, pkt->buf, recvsize, 0, (struct sockaddr *)&pkt->addr, &i); if (!plugins_parse(pkt)) { log_print("scan_receive(): unknown packet: %s:%d size:%d", inet_ntoa(pkt->addr.sin_addr), ntohs(pkt->addr.sin_port), pkt->size); } free(pkt); } } /** * schliesst den server scan socket */ static void scan_close() { close(scan_sock); } /** * scan_init() * initialisiert den socket fuer den server scan * @return false on error */ int scan_init() { struct sockaddr_in dst; int i = 1, port; char *ip; if ((scan_sock = socket(PF_INET, SOCK_DGRAM, 0)) < 0) { log_print("scan_init(): socket()"); return 0; } ip = config_get_string("global", "scan_ip", "0.0.0.0"); port = config_get_int("global", "scan_port", 7130); dst.sin_family = AF_INET; dst.sin_port = htons(port); inet_aton(ip, &dst.sin_addr); if (bind(scan_sock, (struct sockaddr *)&dst, sizeof(dst)) < 0) { log_print("scan_init(): bind()"); return 0; } if (setsockopt(scan_sock, SOL_SOCKET, SO_BROADCAST, &i, sizeof(i))) { log_print("scan_init(): setsockopt()"); return 0; } if (atexit(scan_close) != 0) { log_print("scan_init(): atexit()"); return 0; } log_print("scan socket initialized (%s:%d)", ip, port); return 1; }