diff --git a/config.cpp b/config.cpp index 9ecbb8d..ba67a95 100644 --- a/config.cpp +++ b/config.cpp @@ -17,8 +17,8 @@ Config::Tupel::Tupel(const char* name_, const char* value_) Config::Tupel::~Tupel() { - free(name); - free(value); + free((char*)name); + free((char*)value); } /* ------ */ @@ -33,7 +33,7 @@ Config::Section::~Section() while (!tupelList.isEmpty()) delete tupelList.get(); - free(name); + free((char*)name); } bool Config::Section::addTupel(const char* name, const char* value) @@ -60,9 +60,9 @@ void Config::Section::show() const delete it; } -char* Config::Section::getTupelValue(const char* name) const +const char* Config::Section::getTupelValue(const char* name) const { - char* retval = 0; + const char* retval = 0; Iterator* it = this->tupelList.createIterator(); while (it->hasNext()) { Tupel* t = it->next(); @@ -78,6 +78,40 @@ char* Config::Section::getTupelValue(const char* name) const /* ------ */ +Config::Section::SectionIterator::SectionIterator(Section* section, const char* name) +: nexttup(0), name(name) +{ + it = section->tupelList.createIterator(); +} + +Config::Section::SectionIterator::~SectionIterator() +{ + delete it; +} + +bool Config::Section::SectionIterator::hasNext() +{ + while (it->hasNext()) { + nexttup = it->next(); + if (!strcmp(nexttup->name, name)) + return true; + } + return false; +} + +char* Config::Section::SectionIterator::next() +{ + return (char*)nexttup->value; +} + +void Config::Section::SectionIterator::reset() +{ + it->reset(); + nexttup = 0; +} + +/* ------ */ + Config::~Config() { while (!sectionList.isEmpty()) @@ -93,7 +127,7 @@ Config::Section* Config::addSection(const char* name) bool Config::parseFile(const char* name) { - Config::Section* section = 0; + Section* section = 0; FILE *fz; int i = 0; char *row, *tok, *tok2; @@ -136,9 +170,11 @@ bool Config::parseFile(const char* name) } /* option */ - if ((tok = strtok(row, " \n")) && (tok2 = strtok(NULL, " \n"))) { - if (!section->addTupel(tok, tok2)) - LogSystem::log(LOG_WARN, "config_parse(): invalid row %d", i); + if ((tok = strtok(row, " \n"))) { + while ((tok2 = strtok(NULL, " \n"))) { + if (!section->addTupel(tok, tok2)) + LogSystem::log(LOG_WARN, "config_parse(): invalid row %d", i); + } } } @@ -158,26 +194,32 @@ void Config::show() const delete it; } -char* Config::getParameter(const char* section, const char* option) const +Config::Section* Config::getSection(const char* name) const { - char* retval = 0; - + Section* retval = 0; + Iterator
* it = sectionList.createIterator(); while (it->hasNext()) { Section* s = it->next(); - if (!strcmp(s->name, section)) { - retval = s->getTupelValue(option); + if (!strcmp(s->name, name)) { + retval = s; break; } } - + delete it; return retval; } -char* Config::getString(const char* section, const char* option, char* def) const +const char* Config::getParameter(const char* section, const char* option) const { - char* retval = getParameter(section, option); + Section* s = getSection(section); + return s ? s->getTupelValue(option) : 0; +} + +const char* Config::getString(const char* section, const char* option, char* def) const +{ + const char* retval = getParameter(section, option); if (!retval) { LogSystem::log(LOG_NOTICE, "Config: [%s:%s] not found => using '%s'", @@ -189,7 +231,7 @@ char* Config::getString(const char* section, const char* option, char* def) cons int Config::getInteger(const char* section, const char* option, int def) const { - char* retval = getParameter(section, option); + const char* retval = getParameter(section, option); if (!retval) { LogSystem::log(LOG_NOTICE, "Config: [%s:%s] not found => using '%d'", @@ -198,3 +240,17 @@ int Config::getInteger(const char* section, const char* option, int def) const } return atoi(retval); } + +Iterator* Config::createIterator(const char* section, const char* name) +{ + Section* s = getSection(section); + if (!s) { + LogSystem::log(LOG_NOTICE,"Config: [%s:%s] not found", + section, name); + + return new NullIterator(); + + } else { + return new Config::Section::SectionIterator(s, name); + } +} diff --git a/config.h b/config.h index 65844c1..31c5ea4 100644 --- a/config.h +++ b/config.h @@ -10,36 +10,53 @@ public: bool parseFile(const char* name); void show() const; - char* getParameter(const char* section, const char* name) const; - char* getString(const char* section, const char* name, char* def) const; + const char* getParameter(const char* section, const char* name) const; + const char* getString(const char* section, const char* name, char* def) const; int getInteger(const char* section, const char* name, int def) const; + Iterator* createIterator(const char* section, const char* name); + private: class Tupel { public: Tupel(const char* name, const char* value); ~Tupel(); - char* name; - char* value; + const char* name; + const char* value; }; class Section { public: + class SectionIterator : public Iterator { + public: + SectionIterator(Section* section, const char* name); + ~SectionIterator(); + bool hasNext(); + char* next(); + void reset(); + + private: + Iterator* it; + Tupel* nexttup; + const char* name; + }; + Section(const char* name); ~Section(); bool addTupel(const char* name, const char* option); - char* getTupelValue(const char* name) const; + const char* getTupelValue(const char* name) const; void show() const; - char* name; + const char* name; private: List tupelList; }; Section* addSection(const char* name); + Section* getSection(const char* name) const; List
sectionList; }; diff --git a/gameids.h b/gameids.h new file mode 100644 index 0000000..03b67d6 --- /dev/null +++ b/gameids.h @@ -0,0 +1,63 @@ +#ifndef _GAMEIDS_H_ +#define _GAMEIDS_H_ + +enum { + ID_UNKNOWN = 0, // "Unknown" + ID_HL, // "Halflife" + ID_Q1, // "Quake 1" + ID_Q2, // "Quake 2" + ID_Q3COMP, // "Q3Comp" + ID_UT = 5, // "Unreal Tournament" + ID_Q3A, // "Quake 3 Arena" + ID_EF, // "Elite Force" + ID_RTCW, // "Return to Castle Wolfenstein" + ID_GS1PROT, // "GSProt" + ID_CCR = 10, // "Command & Conquer Renegade" + ID_MOHAA, // "Medal of Honor: Allied Assault" + ID_JK2, // "Jedi Knight 2" + ID_SOF, // "Soldier of Fortune" + ID_UT2K3, // "Unreal Tournament 2003" + ID_AAO = 15, // "America's Army: Operations" + ID_BF1942, // "Battlefield 1942" + ID_AVP2, // "Alien vs. Predator 2" + ID_RUNE, // "Rune" + ID_IGI2, // "Project IGI2: Covert Strike" + ID_NWN = 20, // "Never Winter Nights" + ID_MOHAA_S, // "Medal of Honor: Allied Assault Spearhead" + ID_OPFP, // "Operation Flashpoint" + ID_OPFPR, // "Operation Flashpoint Resistance" + ID_DEVA, // "Devastation" + ID_ET = 25, // "Wolfenstein - Enemy Territory" + ID_EF2, // "Elite Force 2" + ID_JK3, // "Jedi Knight 3" + ID_MOHAA_B, // "Medal of Honor: Allied Assault Breakthrough" + ID_TRIBES2, // "Tribes 2" + ID_HALO = 30, // "Halo" + ID_COD, // "Call of Duty" + ID_SAVAGE, // "Savage: The Battle for Newerth" + ID_UT2K4, // "Unreal Tournament 2004" + ID_HLSTEAM, // "HLSteam" + ID_BFV = 35, // "Battlefield Vietnam" + ID_GS2PROT, // "GS2Prot" + ID_PK, // "Pain Killer" + ID_D3, // "Doom 3" + ID_OGPPROT, // "OGPProt" + ID_HL2 = 40, // "Halflife 2" + ID_TRIBES_V, // "Tribes Vengeance" + ID_COD_UO, // "Call of Duty: United Offensive" + ID_SW_BF, // "Starwars: Battlefront (?)" + ID_SWAT4, // "SWAT 4" + ID_BF2 = 45, // "Battlefield 2" + ID_xxx, // "???" + ID_Q4, // "Quake 4" + ID_COD2 // "Call of Duty 2" +}; + +struct game_ports { + int portlo; + int porthi; + int id; +}; + +#endif // _GAMEIDS_H_ + diff --git a/gameparser.cpp b/gameparser.cpp index 8121ae5..1391579 100644 --- a/gameparser.cpp +++ b/gameparser.cpp @@ -20,6 +20,7 @@ int GameParser::execute(void* arg) while (1) { NetPkt* pkt = rxQueue.getPkt(); int ret = modList.parse(pkt, this); + switch (ret) { case PKT_REJECT: char buf[64]; diff --git a/hlswmaster.conf b/hlswmaster.conf index 9eb90f1..440bd84 100644 --- a/hlswmaster.conf +++ b/hlswmaster.conf @@ -5,6 +5,9 @@ scan_port 7130 # broadcast scan every X seconds scan_interval 10 +# use this interface(s) +scan_deny_iface lo sit0 + # server timeout after X seconds game_timeout 30 @@ -13,4 +16,8 @@ master_ip 0.0.0.0 # logging logfile hlswmaster.log -logprio 7 +logprio DEBUG + +[hlswproxy] +parent 1.1.1.1 2.2.2.2 +parent 3.3.3.3 diff --git a/hlswmaster.cpp b/hlswmaster.cpp index df35e3c..36f5dbd 100644 --- a/hlswmaster.cpp +++ b/hlswmaster.cpp @@ -11,11 +11,15 @@ #include "timerservice.h" #include "modulelist.h" -#include "mod_example.h" +#include "mod_halflife.h" +#include "mod_q3engine.h" +#include "mod_d3engine.h" +#include "mod_gamespy1.h" +#include "mod_gamespy2.h" #define DEFAULT_CONFIG "hlswmaster.conf" #define DEFAULT_LOGFILE "hlswmaster.log" -#define DEFAULT_LOGPRIO LOG_WARN +#define DEFAULT_LOGPRIO "WARN" static struct option opts[] = { {"config", 1, 0, 'c'}, @@ -64,21 +68,29 @@ int main(int argc, char *argv[]) Config conf; conf.parseFile(configfile); -// char* logfile = conf.getString("global", "logfile", DEFAULT_LOGFILE); -// int logprio = conf.getInteger("global", "logprio", DEFAULT_LOGPRIO); -// LogSystem::init(logprio, new FileLog(logfile)); - LogSystem::init(LOG_DEBUG, new StdErrLog()); + const char* logfile = conf.getString("global", "logfile", DEFAULT_LOGFILE); + const char* logprio = conf.getString("global", "logprio", DEFAULT_LOGPRIO); + if (!debug) { + LogSystem::init(logprio, new FileLog(logfile)); + daemon(0, 0); + } else { + LogSystem::init(logprio, new StdErrLog()); + } - LogSystem::log(LOG_EVERYTIME, "hlswmaster-ng startup"); -// conf.show(); + LogSystem::log(LOG_EVERYTIME, "hlswmaster-ng startup (pid:%d)", getpid()); + conf.show(); - ModuleList modList; + ModuleList modList(conf); GameScanner scanner(conf, modList); GameParser parser(conf, scanner, modList); HlswServer server(conf, parser); - modList.reg(new ModExample(conf)); + modList.reg(new ModHalfLife()); + modList.reg(new ModQ3Engine()); + modList.reg(new ModD3Engine()); + modList.reg(new ModGameSpy1()); + modList.reg(new ModGameSpy2()); server.start(); parser.start(); diff --git a/hlswserver.cpp b/hlswserver.cpp index 5f37990..8bb87dd 100644 --- a/hlswserver.cpp +++ b/hlswserver.cpp @@ -16,7 +16,7 @@ HlswServer::HlswServer(Config& conf, GameList& slist) { struct sockaddr_in dst; - char *ip; + const char *ip; if ((sock = socket(PF_INET, SOCK_DGRAM, 0)) < 0) { LogSystem::log(LOG_CRIT, "HlswServer(): socket()"); diff --git a/list.h b/list.h index 49b6d21..655b94b 100644 --- a/list.h +++ b/list.h @@ -7,8 +7,9 @@ template class Iterator { public: virtual ~Iterator() {} - virtual bool hasNext() const =0; + virtual bool hasNext() =0; virtual T* next() =0; + virtual void reset() =0; protected: Iterator() {} @@ -16,6 +17,18 @@ protected: Iterator& operator=(const Iterator& it); }; + +template +class NullIterator : public Iterator { +public: + NullIterator() {} + ~NullIterator() {} + bool hasNext() { return false; } + T* next() { return 0; } + void reset() {} +}; + + template class List { public: @@ -134,7 +147,7 @@ private: : list(list) { // ((ListBase*)list)->mutex.lock(); - pos = &list->head; + reset(); } ~ListIterator() @@ -142,7 +155,7 @@ private: // ((ListBase*)list)->mutex.unlock(); } - bool hasNext() const + bool hasNext() { return (pos->getNext() != &list->head); } @@ -153,6 +166,11 @@ private: return (TT*)pos->getPart(); } + void reset() + { + pos = &list->head; + } + protected: ListIterator(const ListIterator& lit); ListIterator& operator=(const ListIterator& lit); diff --git a/logging.cpp b/logging.cpp index b5d2e82..1d9fcfe 100644 --- a/logging.cpp +++ b/logging.cpp @@ -32,14 +32,39 @@ LogSystem* LogSystem::getInstance() void LogSystem::init(int prio, LogOutput* out) { LogSystem* ls = getInstance(); + if (out) { + if (ls->output) + delete ls->output; - if (ls->output) - delete ls->output; - - ls->output = out; + ls->output = out; + } ls->priority = prio; } +void LogSystem::init(const char* prio, LogOutput* out) +{ + if (!strcasecmp(prio, "DEBUG")) + init(LOG_DEBUG, out); + + else if (!strcasecmp(prio, "INFO")) + init(LOG_INFO, out); + + else if (!strcasecmp(prio, "NOTICE")) + init(LOG_NOTICE, out); + + else if (!strcasecmp(prio, "WARN")) + init(LOG_WARN, out); + + else if (!strcasecmp(prio, "ERROR")) + init(LOG_ERROR, out); + + else if (!strcasecmp(prio, "CRIT")) + init(LOG_CRIT, out); + + else + log(LOG_CRIT, "invalid logging priority"); +} + void LogSystem::log(int prio, const char* fmt, ...) { LogSystem* ls = getInstance(); diff --git a/logging.h b/logging.h index 3460169..89c136d 100644 --- a/logging.h +++ b/logging.h @@ -32,6 +32,7 @@ public: class LogSystem { public: static void init(int prio, LogOutput* lo); + static void init(const char* prio, LogOutput* lo); static void log(int prio, const char* fmt, ...); private: diff --git a/mod_d3engine.cpp b/mod_d3engine.cpp new file mode 100644 index 0000000..eff240f --- /dev/null +++ b/mod_d3engine.cpp @@ -0,0 +1,26 @@ +#include +#include "mod_d3engine.h" + +static struct game_ports port_arr[] = { + { 27666, 27673, ID_D3 }, // Doom 3 + { 28004, 28008, ID_Q4 }, // Quake 4 + { 0,0,0 } +}; + +static const char scanmsg[] = "\xff\xffgetInfo"; +static const char replyhead[] = "\xff\xffinfoResponse"; + +void ModD3Engine::scan(MultiSock* msock) +{ + msock->send(port_arr, scanmsg, strlen(scanmsg)); +} + +int ModD3Engine::parse(NetPkt* pkt, GameList* slist) +{ +// pkt->check_array(arr) +// pkt->check_range(min, max) +// pkt->check_port(port) +// pkt->memcmp(0, buf, len) + + return 0; +} diff --git a/mod_d3engine.h b/mod_d3engine.h new file mode 100644 index 0000000..21712db --- /dev/null +++ b/mod_d3engine.h @@ -0,0 +1,17 @@ +#ifndef _MODD3ENGINE_H_ +#define _MODD3ENGINE_H_ + +#include "module.h" + +class ModD3Engine : public Module { +public: + ModD3Engine() {} + ~ModD3Engine() {} + + void scan(MultiSock* msock); + int parse(NetPkt* pkt, GameList* slist); + + const char* getName() { return "Doom3 engine"; } +}; + +#endif // _MODD3ENGINE_H_ diff --git a/mod_example.h b/mod_example.h deleted file mode 100644 index d7fc8e2..0000000 --- a/mod_example.h +++ /dev/null @@ -1,35 +0,0 @@ -#ifndef _MODEXAMPLE_H_ -#define _MODEXAMPLE_H_ - -#include "modulelist.h" -#include "logging.h" - -class ModExample : public Module { -public: - ModExample(Config& conf) - { - } - - ~ModExample() - { - } - - void scan(MultiSock* msock) - { - LogSystem::log(LOG_DEBUG, "ModExample::scan()"); - } - - int parse(NetPkt* pkt, GameList* slist) - { - LogSystem::log(LOG_DEBUG, "ModExample::parse()"); - return 0; - } - - char* getName() { - return "Example Module"; - } - -protected: -}; - -#endif // _MODEXAMPLE_H_ diff --git a/mod_gamespy1.cpp b/mod_gamespy1.cpp new file mode 100644 index 0000000..854cea4 --- /dev/null +++ b/mod_gamespy1.cpp @@ -0,0 +1,23 @@ +#include +#include "mod_gamespy1.h" + +static struct game_ports port_arr[] = { + { 7777, 7788, ID_UT }, // ut(5), ut2k3(14), rune(18), ut2k4(33), aao(15) + { 22000, 22010, ID_BF1942 }, // bf1942(16) + { 23000, 23010, ID_BFV }, // bfv(35) + { 26001, 26011, ID_IGI2 }, // igi2(19) + { 27888, 27888, ID_AVP2 }, // avp2(17) + { 0,0,0 } +}; + +static const char scanmsg[] = "\\status\\"; + +void ModGameSpy1::scan(MultiSock* msock) +{ + msock->send(port_arr, scanmsg, strlen(scanmsg)); +} + +int ModGameSpy1::parse(NetPkt* pkt, GameList* slist) +{ + return 0; +} diff --git a/mod_gamespy1.h b/mod_gamespy1.h new file mode 100644 index 0000000..62fd84f --- /dev/null +++ b/mod_gamespy1.h @@ -0,0 +1,17 @@ +#ifndef _MODGAMESPY1_H_ +#define _MODGAMESPY1_H_ + +#include "module.h" + +class ModGameSpy1 : public Module { +public: + ModGameSpy1() {} + ~ModGameSpy1() {} + + void scan(MultiSock* msock); + int parse(NetPkt* pkt, GameList* slist); + + const char* getName() { return "GameSpy 1 Protocol"; } +}; + +#endif // _MODGAMESPY1_H_ diff --git a/mod_gamespy2.cpp b/mod_gamespy2.cpp new file mode 100644 index 0000000..0c430c3 --- /dev/null +++ b/mod_gamespy2.cpp @@ -0,0 +1,24 @@ +#include +#include "mod_gamespy2.h" + +static struct game_ports port_arr[] = { + { 7777, 7788, ID_UT }, // ut(5), ut2k3(14), rune(18), ut2k4(33), aao(15) + { 22000, 22010, ID_BF1942 }, // bf1942(16) + { 23000, 23010, ID_BFV }, // bfv(35) + { 26001, 26011, ID_IGI2 }, // igi2(19) + { 27888, 27888, ID_AVP2 }, // avp2(17) + { 0,0,0 } +}; + +static const char scanmsg[] = { 0xFE, 0xFD, 0x00, 0xDE, 0xAD, 0xBE, 0xEF, 0xFF, 0x00, 0x00 }; +static const char replyhead[] = { 0x00, 0xDE, 0xAD, 0xBE, 0xEF }; + +void ModGameSpy2::scan(MultiSock* msock) +{ + msock->send(port_arr, scanmsg, sizeof(scanmsg)); +} + +int ModGameSpy2::parse(NetPkt* pkt, GameList* slist) +{ + return 0; +} diff --git a/mod_gamespy2.h b/mod_gamespy2.h new file mode 100644 index 0000000..004aae7 --- /dev/null +++ b/mod_gamespy2.h @@ -0,0 +1,17 @@ +#ifndef _MODGAMESPY2_H_ +#define _MODGAMESPY2_H_ + +#include "module.h" + +class ModGameSpy2 : public Module { +public: + ModGameSpy2() {} + ~ModGameSpy2() {} + + void scan(MultiSock* msock); + int parse(NetPkt* pkt, GameList* slist); + + const char* getName() { return "GameSpy 2 Protocol"; } +}; + +#endif // _MODGAMESPY1_H_ diff --git a/mod_halflife.cpp b/mod_halflife.cpp new file mode 100644 index 0000000..0f44d32 --- /dev/null +++ b/mod_halflife.cpp @@ -0,0 +1,23 @@ +#include +#include "mod_halflife.h" + +static struct game_ports port_arr[] = { + { 27015, 27024, ID_HL }, + { 0,0,0 } +}; + +static const char scanmsg1[] = "\xff\xff\xff\xff""details"; +static const char scanmsg2[] = "\xff\xff\xff\xff\x54"; +static const char scanmsg3[] = "\xff\xff\xff\xff""TSource Engine Query"; + +void ModHalfLife::scan(MultiSock* msock) +{ + msock->send(port_arr, scanmsg1, strlen(scanmsg1)); + msock->send(port_arr, scanmsg2, strlen(scanmsg2)); + msock->send(port_arr, scanmsg3, strlen(scanmsg3)); +} + +int ModHalfLife::parse(NetPkt* pkt, GameList* slist) +{ + return 0; +} diff --git a/mod_halflife.h b/mod_halflife.h new file mode 100644 index 0000000..d82519d --- /dev/null +++ b/mod_halflife.h @@ -0,0 +1,17 @@ +#ifndef _MODHALFLIFE_H_ +#define _MODHALFLIFE_H_ + +#include "module.h" + +class ModHalfLife : public Module { +public: + ModHalfLife() {} + ~ModHalfLife() {} + + void scan(MultiSock* msock); + int parse(NetPkt* pkt, GameList* slist); + + const char* getName() { return "HalfLife engine"; } +}; + +#endif // _MODHALFLIFE_H_ diff --git a/mod_q3engine.cpp b/mod_q3engine.cpp new file mode 100644 index 0000000..5131aa3 --- /dev/null +++ b/mod_q3engine.cpp @@ -0,0 +1,23 @@ +#include +#include "mod_q3engine.h" + +static struct game_ports port_arr[] = { + { 27960, 27969, ID_Q3A }, // q3(6), ef(7), et25), rtcw(8) + { 28070, 28070, ID_JK2 }, // jk2(12) + { 28960, 28963, ID_COD }, // cod(31), cod:uo(42), cod2(48) + { 29070, 29070, ID_JK3 }, // jk3(27) + { 0,0,0 } +}; + +static const char scanmsg[] = "\xff\xff\xff\xffgetStatus"; +static const char replyhead[] = "\xff\xff\xff\xffstatusResponse"; + +void ModQ3Engine::scan(MultiSock* msock) +{ + msock->send(port_arr, scanmsg, strlen(scanmsg)); +} + +int ModQ3Engine::parse(NetPkt* pkt, GameList* slist) +{ + return 0; +} diff --git a/mod_q3engine.h b/mod_q3engine.h new file mode 100644 index 0000000..28c6142 --- /dev/null +++ b/mod_q3engine.h @@ -0,0 +1,17 @@ +#ifndef _MODQ3ENGINE_H_ +#define _MODQ3ENGINE_H_ + +#include "module.h" + +class ModQ3Engine : public Module { +public: + ModQ3Engine() {} + ~ModQ3Engine() {} + + void scan(MultiSock* msock); + int parse(NetPkt* pkt, GameList* slist); + + const char* getName() { return "Quake3 engine"; } +}; + +#endif // _MODQ3ENGINE_H_ diff --git a/module.h b/module.h new file mode 100644 index 0000000..3fdb467 --- /dev/null +++ b/module.h @@ -0,0 +1,23 @@ +#ifndef _MODULE_H_ +#define _MODULE_H_ + +#include "config.h" +#include "multisock.h" +#include "netpkt.h" +#include "gamelist.h" + +class Module { +public: + virtual ~Module() {}; + virtual void init(Config* conf) {} + virtual void scan(MultiSock* msock) =0; + virtual int parse(NetPkt* pkt, GameList* slist) =0; + virtual const char* getName() =0; + +protected: + Module() {}; + Module(const Module& ml); + Module& operator=(const Module& ml); +}; + +#endif // _MODULE_H_ diff --git a/modulelist.cpp b/modulelist.cpp index e52919d..ec8ecdc 100644 --- a/modulelist.cpp +++ b/modulelist.cpp @@ -1,7 +1,8 @@ #include "logging.h" #include "modulelist.h" -ModuleList::ModuleList() +ModuleList::ModuleList(Config& conf) +: conf(conf) { } @@ -13,7 +14,8 @@ ModuleList::~ModuleList() void ModuleList::reg(Module* mod) { - LogSystem::log(LOG_NOTICE, "Loading Module '%s'", mod->getName()); + LogSystem::log(LOG_NOTICE, "Registering module '%s'", mod->getName()); + mod->init(&conf); mlist.addTail(mod); } diff --git a/modulelist.h b/modulelist.h index 7d2ed62..32c6466 100644 --- a/modulelist.h +++ b/modulelist.h @@ -1,27 +1,15 @@ #ifndef _MODULELIST_H_ #define _MODULELIST_H_ +#include "config.h" #include "multisock.h" #include "netpkt.h" #include "gamelist.h" -#include "config.h" - -class Module { -public: - virtual ~Module() {}; - - virtual void scan(MultiSock* msock) =0; - virtual int parse(NetPkt* pkt, GameList* slist) =0; - virtual char* getName() =0; - -protected: - Module() {}; -}; - +#include "module.h" class ModuleList { public: - ModuleList(); + ModuleList(Config& conf); ~ModuleList(); void reg(Module* mod); @@ -35,6 +23,7 @@ protected: private: List mlist; + Config& conf; }; #endif // _MODULELIST_H_ diff --git a/multisock.cpp b/multisock.cpp index 3ccee4c..d5c71c7 100644 --- a/multisock.cpp +++ b/multisock.cpp @@ -131,26 +131,40 @@ MultiSock::MultiSock(Config& conf) fgets(buf, BUFSIZE, fp); int port = conf.getInteger("global", "scan_port", DEFAULT_PORT); - FD_ZERO(&fdsel); + Iterator* it = conf.createIterator("global", "scan_deny_iface"); + FD_ZERO(&fdsel); while (fgets(buf, BUFSIZE, fp) != NULL) { char* tok = strtok(buf, " :"); - - // TODO: check against config list - 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); + 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() @@ -179,9 +193,42 @@ int MultiSock::waitOnSocket() } delete it; - LogSystem::log(LOG_WARN, "getRecvSocket(): select()"); + LogSystem::log(LOG_WARN, "waitOnSocket(): select()"); } return -1; } +void MultiSock::send(struct in_addr *dstip, int dport, const char* data, int size) +{ + struct sockaddr_in addr; + addr.sin_family = AF_INET; + addr.sin_port = htons(dport); + addr.sin_addr.s_addr = (dstip ? dstip->s_addr : 0xFFFFFFFF); + + Iterator* it = ifaceList.createIterator(); + while (it->hasNext()) + if (sendto(it->next()->getFD(), data, size, 0, (struct sockaddr *)&addr, sizeof(addr)) < 0) + LogSystem::log(LOG_WARN, "MultiSock::send()"); + + delete it; + + usleep(10000); +} + +void MultiSock::send(struct game_ports* arr, const char* data, int size) +{ + while (arr && arr->portlo && arr->porthi) { + int port; + for (port = arr->portlo; port <= arr->porthi; port++) + send(NULL, port, data, size); + + arr++; + } +} + +void MultiSock::send(int* arr, const char* data, int size) +{ + while (*arr) + send(NULL, *arr++, data, size); +} diff --git a/multisock.h b/multisock.h index 36b0627..b4c140b 100644 --- a/multisock.h +++ b/multisock.h @@ -6,13 +6,17 @@ #include "list.h" #include "config.h" +#include "gameids.h" class MultiSock { public: MultiSock(Config& conf); ~MultiSock(); - int send(struct in_addr *dstip, int dport, char* data, int size); + void send(struct in_addr *dstip, int dport, const char* data, int size); + void send(struct game_ports* arr, const char* data, int size); + void send(int* arr, const char* data, int size); + int waitOnSocket(); protected: