hlswmaster-ng/multisock.cpp

114 lines
2.2 KiB
C++

#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <string.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <sys/ioctl.h>
#include <net/if.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include "multisock.h"
#include "logging.h"
#define DEFAULT_PORT 7130
#define DEVFILE "/proc/net/dev"
#define BUFSIZE 1024
MultiSock::MultiSock(Config& conf)
{
char* buf = new char [BUFSIZE];
if (buf == NULL) {
LogSystem::log(LOG_CRIT, "MultiSock(): out of memory");
return;
}
FILE* fp = fopen(DEVFILE, "r");
if (fp == NULL) {
LogSystem::log(LOG_CRIT, "MultiSock(): can not open " DEVFILE);
free(buf);
return;
}
fgets(buf, BUFSIZE, fp);
fgets(buf, BUFSIZE, fp);
int port = conf.getInteger("global", "scan_port", DEFAULT_PORT);
Iterator<char>* it = conf.createIterator("global", "scan_deny_iface");
FD_ZERO(&fdsel);
while (fgets(buf, BUFSIZE, fp) != NULL) {
char* tok = strtok(buf, " :");
it->reset();
while (it->hasNext()) {
if (!strcmp(it->next(), tok)) {
LogSystem::log(LOG_NOTICE, "Interface '%s' denied by config", tok);
tok = 0;
break;
}
}
if (tok) {
Socket* sock = Socket::createSocket(tok, port);
if (sock) {
FD_SET(sock->getFD(), &fdsel);
sock->show(buf, BUFSIZE);
LogSystem::log(LOG_NOTICE, "adding Interface %s", buf);
ifaceList.add(sock);
}
}
}
delete it;
fclose(fp);
delete buf;
if (ifaceList.isEmpty())
LogSystem::log(LOG_CRIT, "No useable Interfaces found!");
}
MultiSock::~MultiSock()
{
while (!ifaceList.isEmpty())
delete ifaceList.get();
}
NetPkt* MultiSock::recv()
{
fd_set fdcpy;
while (1) {
memcpy(&fdcpy, &fdsel, sizeof(fdcpy));
select(FD_SETSIZE, &fdcpy, NULL, NULL, NULL);
Iterator<Socket>* it = ifaceList.createIterator();
while (it->hasNext()) {
Socket* sock = it->next();
if (FD_ISSET(sock->getFD(), &fdcpy)) {
delete it;
return sock->recv();
}
}
delete it;
LogSystem::log(LOG_WARN, "MultiSock::recvFrom(): select()");
}
return NULL;
}
int MultiSock::sendto(NetPkt* pkt, struct sockaddr_in* dst)
{
Iterator<Socket>* it = ifaceList.createIterator();
while (it->hasNext())
it->next()->sendto(pkt, dst);
delete it;
usleep(1000);
return 0;
}