daily work
This commit is contained in:
parent
e0b98f4756
commit
33e97b1eaa
2
config.h
2
config.h
|
@ -34,6 +34,8 @@ private:
|
||||||
~SectionIterator();
|
~SectionIterator();
|
||||||
bool hasNext();
|
bool hasNext();
|
||||||
char* next();
|
char* next();
|
||||||
|
void add(char* part) {}
|
||||||
|
void remove() {}
|
||||||
void reset();
|
void reset();
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
|
|
@ -26,7 +26,6 @@ void GameList::cleanup()
|
||||||
|
|
||||||
long GameList::getLastUpdate()
|
long GameList::getLastUpdate()
|
||||||
{
|
{
|
||||||
lastUpdate++;
|
|
||||||
return lastUpdate;
|
return lastUpdate;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -35,11 +34,12 @@ Iterator<GameEntry>* GameList::createIterator()
|
||||||
return glist.createIterator();
|
return glist.createIterator();
|
||||||
}
|
}
|
||||||
|
|
||||||
void GameList::addGame(int gameid, NetPkt* pkt, int port2)
|
void GameList::addGame(int gameid, NetPkt* pkt, int port2, bool swap)
|
||||||
{
|
{
|
||||||
char buf[64];
|
char buf[64];
|
||||||
pkt->show(buf, sizeof(buf));
|
pkt->show(buf, sizeof(buf));
|
||||||
LogSystem::log(LOG_NOTICE, "Adding Game %d: %s %d", gameid, buf, port2);
|
LogSystem::log(LOG_NOTICE, "Adding Game %d: %s", gameid, buf);
|
||||||
|
|
||||||
glist.add(new GameEntry());
|
glist.add(new GameEntry());
|
||||||
|
lastUpdate++;
|
||||||
}
|
}
|
||||||
|
|
|
@ -13,7 +13,7 @@ public:
|
||||||
~GameList();
|
~GameList();
|
||||||
|
|
||||||
void cleanup();
|
void cleanup();
|
||||||
void addGame(int gameid, NetPkt* pkt, int port2 = 0);
|
void addGame(int gameid, NetPkt* pkt, int port2 = 0, bool swap = false);
|
||||||
|
|
||||||
long getLastUpdate();
|
long getLastUpdate();
|
||||||
Iterator<GameEntry>* createIterator();
|
Iterator<GameEntry>* createIterator();
|
||||||
|
|
|
@ -9,21 +9,35 @@ GameParser::GameParser(RecvQueue& rxQueue, ModuleList& modList, GameList& gameLi
|
||||||
|
|
||||||
int GameParser::execute(void* arg)
|
int GameParser::execute(void* arg)
|
||||||
{
|
{
|
||||||
|
NetPkt* pkt;
|
||||||
|
char buf[64], *p;
|
||||||
|
int ret;
|
||||||
|
|
||||||
while (1) {
|
while (1) {
|
||||||
NetPkt* pkt = rxQueue.getPkt();
|
pkt = rxQueue.getPkt();
|
||||||
int ret = modList.parse(pkt, &gameList);
|
ret = modList.parse(pkt, &gameList);
|
||||||
|
|
||||||
switch (ret) {
|
switch (ret) {
|
||||||
case PARSE_REJECT:
|
case PARSE_ACCEPT_FAKE:
|
||||||
char buf[64];
|
|
||||||
pkt->show(buf, sizeof(buf));
|
pkt->show(buf, sizeof(buf));
|
||||||
LogSystem::log(LOG_NOTICE, "unknown Packet: %s", buf);
|
LogSystem::log(LOG_NOTICE, "not supported Game: %s", buf);
|
||||||
|
|
||||||
case PARSE_ACCEPT:
|
case PARSE_ACCEPT:
|
||||||
delete pkt;
|
delete pkt;
|
||||||
|
|
||||||
case PARSE_ACCEPT_FREED:
|
case PARSE_ACCEPT_FREED:
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
default:
|
||||||
|
case PARSE_REJECT:
|
||||||
|
pkt->show(buf, sizeof(buf));
|
||||||
|
LogSystem::log(LOG_NOTICE, "unknown Packet: %s", buf);
|
||||||
|
|
||||||
|
p = pkt->showfull();
|
||||||
|
LogSystem::log(LOG_DEBUG, "%s", p);
|
||||||
|
delete p;
|
||||||
|
delete pkt;
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return 0;
|
return 0;
|
||||||
|
|
|
@ -91,9 +91,9 @@ int main(int argc, char *argv[])
|
||||||
HlswServer server(conf, gameList);
|
HlswServer server(conf, gameList);
|
||||||
|
|
||||||
// modList.reg(new ModHalfLife());
|
// modList.reg(new ModHalfLife());
|
||||||
modList.reg(new ModQ3Engine());
|
// modList.reg(new ModQ3Engine());
|
||||||
// modList.reg(new ModD3Engine());
|
// modList.reg(new ModD3Engine());
|
||||||
// modList.reg(new ModGameSpy1());
|
modList.reg(new ModGameSpy1());
|
||||||
// modList.reg(new ModGameSpy2());
|
// modList.reg(new ModGameSpy2());
|
||||||
|
|
||||||
server.start();
|
server.start();
|
||||||
|
|
|
@ -9,11 +9,8 @@
|
||||||
#include "logging.h"
|
#include "logging.h"
|
||||||
#include "hlswserver.h"
|
#include "hlswserver.h"
|
||||||
|
|
||||||
#define HLSW_MASTER_PORT 7140
|
|
||||||
static const char hlsw_header[] = "\xFF\xFF\xFF\xFFHLSWLANSEARCH";
|
static const char hlsw_header[] = "\xFF\xFF\xFF\xFFHLSWLANSEARCH";
|
||||||
|
|
||||||
#define DEFAULT_REBUILD_INTERVAL 5
|
|
||||||
|
|
||||||
struct hlsw_entry {
|
struct hlsw_entry {
|
||||||
uint16_t gameid;
|
uint16_t gameid;
|
||||||
uint32_t ip;
|
uint32_t ip;
|
||||||
|
@ -21,11 +18,15 @@ struct hlsw_entry {
|
||||||
uint16_t port2;
|
uint16_t port2;
|
||||||
} __attribute__ ((packed));
|
} __attribute__ ((packed));
|
||||||
|
|
||||||
|
#define HLSW_MASTER_PORT 7140
|
||||||
|
#define HLSW_MAX_PACKET_SIZE (sizeof(hlsw_header) + 140 * sizeof(struct hlsw_entry))
|
||||||
|
#define DEFAULT_REBUILD_INTERVAL 5
|
||||||
|
|
||||||
HlswServer::HlswPacket::HlswPacket(HlswPacket* next)
|
HlswServer::HlswPacket::HlswPacket(HlswPacket* next)
|
||||||
: NetPkt(1418), next(next)
|
: NetPkt(HLSW_MAX_PACKET_SIZE), next(next)
|
||||||
{
|
{
|
||||||
memcpy((void*)data, hlsw_header, sizeof(hlsw_header));
|
memcpy((void*)data, hlsw_header, sizeof(hlsw_header));
|
||||||
used = sizeof(hlsw_header);
|
size = sizeof(hlsw_header);
|
||||||
}
|
}
|
||||||
|
|
||||||
HlswServer::HlswPacket::~HlswPacket()
|
HlswServer::HlswPacket::~HlswPacket()
|
||||||
|
@ -36,7 +37,7 @@ HlswServer::HlswPacket::~HlswPacket()
|
||||||
|
|
||||||
bool HlswServer::HlswPacket::addGame(GameEntry* ge)
|
bool HlswServer::HlswPacket::addGame(GameEntry* ge)
|
||||||
{
|
{
|
||||||
if (used >= 1418)
|
if (size >= HLSW_MAX_PACKET_SIZE)
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
struct hlsw_entry tmp;
|
struct hlsw_entry tmp;
|
||||||
|
@ -45,8 +46,8 @@ bool HlswServer::HlswPacket::addGame(GameEntry* ge)
|
||||||
tmp.port1 = ge->port1;
|
tmp.port1 = ge->port1;
|
||||||
tmp.port2 = ge->port2;
|
tmp.port2 = ge->port2;
|
||||||
|
|
||||||
memcpy((void*)(data + used), &tmp, sizeof(tmp));
|
memcpy((void*)(data + size), &tmp, sizeof(tmp));
|
||||||
used += sizeof(tmp);
|
size += sizeof(tmp);
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -99,7 +100,6 @@ int HlswServer::execute(void* arg)
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void HlswServer::rebuild(GameList& glist) {
|
void HlswServer::rebuild(GameList& glist) {
|
||||||
if (glist.getLastUpdate() > lastUpdate) {
|
if (glist.getLastUpdate() > lastUpdate) {
|
||||||
HlswPacket* newlist = new HlswPacket(NULL);
|
HlswPacket* newlist = new HlswPacket(NULL);
|
||||||
|
|
258
list.h
258
list.h
|
@ -3,183 +3,145 @@
|
||||||
|
|
||||||
#include "mutex.h"
|
#include "mutex.h"
|
||||||
|
|
||||||
template <class T>
|
class IteratorBase {
|
||||||
class Iterator {
|
|
||||||
public:
|
public:
|
||||||
virtual ~Iterator() {}
|
virtual ~IteratorBase() {}
|
||||||
virtual bool hasNext() =0;
|
virtual bool hasNext() =0;
|
||||||
virtual T* next() =0;
|
virtual void* next() =0;
|
||||||
|
virtual void add(void* part) {}; // TODO: why not =0;
|
||||||
|
virtual void remove() =0;
|
||||||
virtual void reset() =0;
|
virtual void reset() =0;
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
Iterator<T>() {}
|
IteratorBase() {}
|
||||||
Iterator<T>(const Iterator<T>& it);
|
IteratorBase(const IteratorBase& it);
|
||||||
Iterator<T>& operator=(const Iterator<T>& it);
|
IteratorBase& operator=(const IteratorBase& it);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
class ListBase {
|
||||||
|
public:
|
||||||
|
ListBase();
|
||||||
|
~ListBase();
|
||||||
|
|
||||||
|
void add(const void* part);
|
||||||
|
void addTail(const void* part);
|
||||||
|
void* get();
|
||||||
|
void* getTail();
|
||||||
|
bool isEmpty() const;
|
||||||
|
|
||||||
|
IteratorBase* createIterator();
|
||||||
|
|
||||||
|
protected:
|
||||||
|
ListBase(const ListBase& l);
|
||||||
|
ListBase& operator=(const ListBase& l);
|
||||||
|
|
||||||
|
class ListEntryBase {
|
||||||
|
public:
|
||||||
|
ListEntryBase(const void* part = 0);
|
||||||
|
~ListEntryBase();
|
||||||
|
|
||||||
|
void add(ListEntryBase* prev, ListEntryBase* next);
|
||||||
|
void del();
|
||||||
|
bool isEmpty() const;
|
||||||
|
|
||||||
|
void* getPart() const;
|
||||||
|
ListEntryBase* getPrev() const;
|
||||||
|
ListEntryBase* getNext() const;
|
||||||
|
|
||||||
|
protected:
|
||||||
|
ListEntryBase(const ListEntryBase& l);
|
||||||
|
ListEntryBase& operator=(const ListEntryBase& l);
|
||||||
|
|
||||||
|
private:
|
||||||
|
ListEntryBase* prev;
|
||||||
|
ListEntryBase* next;
|
||||||
|
const void* part;
|
||||||
|
};
|
||||||
|
|
||||||
|
class ListIteratorBase : public IteratorBase {
|
||||||
|
public:
|
||||||
|
ListIteratorBase(ListBase* list);
|
||||||
|
~ListIteratorBase();
|
||||||
|
|
||||||
|
bool hasNext();
|
||||||
|
void* next();
|
||||||
|
void add(void* part);
|
||||||
|
void remove();
|
||||||
|
void reset();
|
||||||
|
|
||||||
|
private:
|
||||||
|
ListBase* list;
|
||||||
|
ListEntryBase* pos;
|
||||||
|
};
|
||||||
|
|
||||||
|
private:
|
||||||
|
ListEntryBase head;
|
||||||
|
Mutex mutex;
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
template <class T>
|
||||||
|
class Iterator : public IteratorBase {
|
||||||
|
public:
|
||||||
|
virtual T* next() =0;
|
||||||
|
virtual void add(T* part) =0;
|
||||||
|
};
|
||||||
|
|
||||||
template <class T>
|
template <class T>
|
||||||
class NullIterator : public Iterator<T> {
|
class NullIterator : public Iterator<T> {
|
||||||
public:
|
public:
|
||||||
NullIterator() {}
|
NullIterator() {}
|
||||||
~NullIterator() {}
|
~NullIterator() {}
|
||||||
bool hasNext() { return false; }
|
|
||||||
T* next() { return 0; }
|
bool hasNext() { return false; }
|
||||||
void reset() {}
|
T* next() { return NULL; }
|
||||||
|
void add(T* part) {}
|
||||||
|
void remove() {}
|
||||||
|
void reset() {}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
template <class T>
|
template <class T>
|
||||||
class List {
|
class List : private ListBase {
|
||||||
public:
|
public:
|
||||||
List() {}
|
List() {}
|
||||||
|
~List() {}
|
||||||
|
|
||||||
~List()
|
void add(const T* part) { ListBase::add(part); }
|
||||||
{
|
void addTail(const T* part) { ListBase::addTail(part); }
|
||||||
AutoMutex am(mutex);
|
T* get() { return (T*)ListBase::get(); }
|
||||||
while(!head.isEmpty())
|
T* getTail() { return (T*)ListBase::getTail(); }
|
||||||
head.getNext()->del();
|
bool isEmpty() const { return ListBase::isEmpty(); }
|
||||||
}
|
|
||||||
|
|
||||||
void add(const T* part)
|
Iterator<T>* createIterator() const { return new ListIteratorRO<T>(this); }
|
||||||
{
|
Iterator<T>* createIteratorRW() { return new ListIteratorRW<T>(this); }
|
||||||
ListEntry<T>* entry = new ListEntry<T>(part);
|
|
||||||
|
|
||||||
AutoMutex am(mutex);
|
|
||||||
entry->add(&head, head.getNext());
|
|
||||||
}
|
|
||||||
|
|
||||||
void addTail(const T* part)
|
|
||||||
{
|
|
||||||
ListEntry<T>* entry = new ListEntry<T>(part);
|
|
||||||
|
|
||||||
AutoMutex am(mutex);
|
|
||||||
entry->add(head.getPrev(), &head);
|
|
||||||
}
|
|
||||||
|
|
||||||
T* get()
|
|
||||||
{
|
|
||||||
AutoMutex am(mutex);
|
|
||||||
ListEntry<T>* entry = head.getNext();
|
|
||||||
T* retval = (T*)entry->getPart();
|
|
||||||
|
|
||||||
if (!head.isEmpty()) {
|
|
||||||
entry->del();
|
|
||||||
delete entry;
|
|
||||||
}
|
|
||||||
return retval;
|
|
||||||
}
|
|
||||||
|
|
||||||
T* getTail()
|
|
||||||
{
|
|
||||||
AutoMutex am(mutex);
|
|
||||||
ListEntry<T>* entry = head.getPrev();
|
|
||||||
T* retval = (T*)entry->getPart();
|
|
||||||
|
|
||||||
if (!head.isEmpty()) {
|
|
||||||
entry->del();
|
|
||||||
delete entry;
|
|
||||||
}
|
|
||||||
return retval;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool isEmpty() const
|
|
||||||
{
|
|
||||||
AutoMutex am((Mutex&)mutex);
|
|
||||||
return head.isEmpty();
|
|
||||||
}
|
|
||||||
|
|
||||||
Iterator<T>* createIterator() const
|
|
||||||
{
|
|
||||||
return new ListIterator<T>(this);
|
|
||||||
}
|
|
||||||
|
|
||||||
protected:
|
|
||||||
List(const List& l);
|
|
||||||
List& operator=(const List& l);
|
|
||||||
|
|
||||||
private:
|
private:
|
||||||
template <class TT>
|
template <class TT>
|
||||||
class ListEntry {
|
class ListIteratorRO : public Iterator<TT>, private ListIteratorBase {
|
||||||
public:
|
public:
|
||||||
ListEntry(const TT* part = 0)
|
ListIteratorRO(const List<TT>* list) : ListIteratorBase((ListBase*)list) {}
|
||||||
: prev(this), next(this), part(part)
|
~ListIteratorRO() {}
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
void add(ListEntry<TT>* prev_, ListEntry<TT>* next_)
|
bool hasNext() { return ListIteratorBase::hasNext(); }
|
||||||
{
|
TT* next() { return (TT*)ListIteratorBase::next(); }
|
||||||
this->next = next_;
|
void add(TT* part) {}
|
||||||
this->prev = prev_;
|
void remove() {}
|
||||||
next_->prev = this;
|
void reset() { ListIteratorBase::reset(); }
|
||||||
prev_->next = this;
|
|
||||||
}
|
|
||||||
|
|
||||||
void del()
|
|
||||||
{
|
|
||||||
next->prev = prev;
|
|
||||||
prev->next = next;
|
|
||||||
next = prev = this;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool isEmpty() const
|
|
||||||
{
|
|
||||||
return (this->prev == this) && (this->next == this);
|
|
||||||
}
|
|
||||||
|
|
||||||
const TT* getPart() const { return part; }
|
|
||||||
ListEntry<TT>* getPrev() const { return prev; }
|
|
||||||
ListEntry<TT>* getNext() const { return next; }
|
|
||||||
|
|
||||||
private:
|
|
||||||
ListEntry<TT>* prev;
|
|
||||||
ListEntry<TT>* next;
|
|
||||||
const TT* part;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
ListEntry<T> head;
|
|
||||||
Mutex mutex;
|
|
||||||
|
|
||||||
template <class TT>
|
template <class TT>
|
||||||
class ListIterator : public Iterator<TT> {
|
class ListIteratorRW : public Iterator<TT>, private ListIteratorBase {
|
||||||
public:
|
public:
|
||||||
ListIterator(const List<TT>* list)
|
ListIteratorRW(List<TT>* list) : ListIteratorBase(list) {}
|
||||||
: list(list)
|
~ListIteratorRW() {}
|
||||||
{
|
|
||||||
((List<TT>*)list)->mutex.lock();
|
|
||||||
reset();
|
|
||||||
}
|
|
||||||
|
|
||||||
~ListIterator()
|
bool hasNext() { return ListIteratorBase::hasNext(); }
|
||||||
{
|
TT* next() { return (TT*)ListIteratorBase::next(); }
|
||||||
((List<TT>*)list)->mutex.unlock();
|
void add(TT* part) { ListIteratorBase::add(part); }
|
||||||
}
|
void remove() { ListIteratorBase::remove(); }
|
||||||
|
void reset() { ListIteratorBase::reset(); }
|
||||||
bool hasNext()
|
|
||||||
{
|
|
||||||
return (pos->getNext() != &list->head);
|
|
||||||
}
|
|
||||||
|
|
||||||
TT* next()
|
|
||||||
{
|
|
||||||
pos = pos->getNext();
|
|
||||||
return (TT*)pos->getPart();
|
|
||||||
}
|
|
||||||
|
|
||||||
void reset()
|
|
||||||
{
|
|
||||||
pos = &list->head;
|
|
||||||
}
|
|
||||||
|
|
||||||
protected:
|
|
||||||
ListIterator(const ListIterator& lit);
|
|
||||||
ListIterator& operator=(const ListIterator& lit);
|
|
||||||
|
|
||||||
private:
|
|
||||||
const List<TT>* list;
|
|
||||||
const ListEntry<TT>* pos;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
#endif //_LIST_H_
|
#endif //_LIST_H_
|
||||||
|
|
|
@ -7,8 +7,8 @@
|
||||||
|
|
||||||
#include "logging.h"
|
#include "logging.h"
|
||||||
|
|
||||||
#define BUFLEN 1024
|
/* we need this for packet dumps! */
|
||||||
|
#define BUFLEN 8192
|
||||||
|
|
||||||
LogSystem::LogSystem() : output(0), priority(0)
|
LogSystem::LogSystem() : output(0), priority(0)
|
||||||
{
|
{
|
||||||
|
|
|
@ -25,7 +25,7 @@ int ModD3Engine::parse(NetPkt* pkt, GameList* glist)
|
||||||
if (!gameid)
|
if (!gameid)
|
||||||
return PARSE_REJECT;
|
return PARSE_REJECT;
|
||||||
|
|
||||||
if (pkt->compare(0, replyhead, strlen(replyhead)))
|
if (!pkt->compare(0, replyhead, strlen(replyhead)))
|
||||||
return PARSE_REJECT;
|
return PARSE_REJECT;
|
||||||
|
|
||||||
glist->addGame(gameid, pkt);
|
glist->addGame(gameid, pkt);
|
||||||
|
|
251
mod_gamespy1.cpp
251
mod_gamespy1.cpp
|
@ -1,24 +1,267 @@
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
|
#include "logging.h"
|
||||||
#include "modhelper.h"
|
#include "modhelper.h"
|
||||||
#include "mod_gamespy1.h"
|
#include "mod_gamespy1.h"
|
||||||
|
|
||||||
static struct game_ports port_arr[] = {
|
static struct game_ports port_arr[] = {
|
||||||
{ 7777, 7788, ID_UT }, // ut(5), ut2k3(14), rune(18), ut2k4(33), aao(15)
|
{ 7777, 7788, ID_UT }, // ut, ut2k3, rune, ut2k4, aao, POSTAL2
|
||||||
{ 22000, 22010, ID_BF1942 }, // bf1942(16)
|
{ 22000, 22010, ID_BF1942 }, // bf1942(16)
|
||||||
{ 23000, 23010, ID_BFV }, // bfv(35)
|
{ 23000, 23010, ID_BFV }, // bfv(35)
|
||||||
{ 26001, 26011, ID_IGI2 }, // igi2(19)
|
{ 26001, 26011, ID_IGI2 }, // igi2(19)
|
||||||
{ 27888, 27888, ID_AVP2 }, // avp2(17)
|
{ 27888, 27888, ID_AVP2 }, // avp2(17), FEAR
|
||||||
{ 0,0,0 }
|
{ 0,0,0 }
|
||||||
};
|
};
|
||||||
|
|
||||||
static const char scanmsg[] = "\\status\\";
|
static const char scanmsg[] = "\\status\\";
|
||||||
|
static const char search_queryid[] = "\\queryid\\";
|
||||||
|
static const char search_final[] = "\\final\\";
|
||||||
|
|
||||||
|
static const char search_hostport[] = "\\hostport\\";
|
||||||
|
static const char search_gamename[] = "\\gamename\\";
|
||||||
|
static const char search_gsgamename[] = "\\gsgamename\\";
|
||||||
|
static const char search_gameid[] = "\\game_id\\";
|
||||||
|
|
||||||
|
static const char reply_ut[] = "ut\\";
|
||||||
|
static const char reply_ut2k3[] = "ut2\\";
|
||||||
|
static const char reply_ut2k4[] = "ut2004\\";
|
||||||
|
static const char reply_bf1942[] = "bfield1942\\";
|
||||||
|
static const char reply_bfv1[] = "bfvietnam\\";
|
||||||
|
static const char reply_bfv2[] = "BFVIETNAM\\";
|
||||||
|
static const char reply_poe[] = "poe\\";
|
||||||
|
static const char reply_opk[] = "opk\\";
|
||||||
|
static const char reply_avp2[] = "avp2\\";
|
||||||
|
static const char reply_igi2[] = "projectigi2r\\";
|
||||||
|
static const char reply_aao[] = "armygame\\";
|
||||||
|
static const char reply_rune[] = "rune\\";
|
||||||
|
static const char reply_postal2[] = "postal2\\";
|
||||||
|
static const char reply_fear[] = "fear\\";
|
||||||
|
|
||||||
|
ModGameSpy1::ModGameSpy1()
|
||||||
|
{
|
||||||
|
// TODO: cleanup event
|
||||||
|
}
|
||||||
|
|
||||||
|
ModGameSpy1::~ModGameSpy1()
|
||||||
|
{
|
||||||
|
while (!list.isEmpty()) {
|
||||||
|
MultiPart* mp = list.get();
|
||||||
|
delete mp->pkt;
|
||||||
|
delete mp;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
void ModGameSpy1::scan(MultiSock* msock)
|
void ModGameSpy1::scan(MultiSock* msock)
|
||||||
{
|
{
|
||||||
ModHelper::send(msock, port_arr, scanmsg, strlen(scanmsg));
|
ModHelper::send(msock, port_arr, scanmsg, strlen(scanmsg));
|
||||||
}
|
}
|
||||||
|
|
||||||
int ModGameSpy1::parse(NetPkt* pkt, GameList* slist)
|
int ModGameSpy1::parse(NetPkt* pkt, GameList* glist)
|
||||||
{
|
{
|
||||||
return 0;
|
NetPkt* pkt2;
|
||||||
|
int gameid, pos, offset, queryid, subid, retval;
|
||||||
|
bool final;
|
||||||
|
|
||||||
|
gameid = ModHelper::checkPorts(pkt, port_arr);
|
||||||
|
if (!gameid)
|
||||||
|
return PARSE_REJECT;
|
||||||
|
|
||||||
|
/* eat ut connection attemps */
|
||||||
|
if (gameid == 5 && pkt->getSize() <= 6)
|
||||||
|
return PARSE_ACCEPT_QUIRK;
|
||||||
|
|
||||||
|
offset = pkt->find(0, search_queryid, strlen(search_queryid));
|
||||||
|
if (offset == -1)
|
||||||
|
return PARSE_REJECT;
|
||||||
|
|
||||||
|
pos = offset + strlen(search_queryid);
|
||||||
|
offset = pkt->parse_int(pos, &queryid);
|
||||||
|
if (offset == 0)
|
||||||
|
return PARSE_REJECT;
|
||||||
|
|
||||||
|
pos += offset +1;
|
||||||
|
offset = pkt->parse_int(pos, &subid);
|
||||||
|
if (offset == 0)
|
||||||
|
return PARSE_REJECT;
|
||||||
|
|
||||||
|
offset = pkt->find(0, search_final, strlen(search_final));
|
||||||
|
final = (offset != -1);
|
||||||
|
|
||||||
|
/* single final packet -> shortcut */
|
||||||
|
if (final && (subid == 1)) {
|
||||||
|
LogSystem::log(LOG_DEBUG, "single final");
|
||||||
|
pkt2 = pkt;
|
||||||
|
|
||||||
|
/* non-final multi-part */
|
||||||
|
} else if (!final) {
|
||||||
|
LogSystem::log(LOG_DEBUG, "non final");
|
||||||
|
list.addTail(new MultiPart(pkt, queryid, subid));
|
||||||
|
return PARSE_ACCEPT_FREED;
|
||||||
|
|
||||||
|
/* final multipart */
|
||||||
|
} else {
|
||||||
|
LogSystem::log(LOG_DEBUG, "multi final");
|
||||||
|
pkt2 = merge(pkt, queryid, subid);
|
||||||
|
if (pkt2 == NULL) {
|
||||||
|
LogSystem::log(LOG_NOTICE, "GameSpy1: unable to merge");
|
||||||
|
return PARSE_ACCEPT_FREED;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
retval = parse_real(pkt2, glist, gameid);
|
||||||
|
|
||||||
|
if (pkt2 != pkt)
|
||||||
|
delete pkt2;
|
||||||
|
|
||||||
|
return retval;
|
||||||
|
}
|
||||||
|
|
||||||
|
ModGameSpy1::MultiPart::MultiPart(NetPkt* pkt, int queryid, int subid)
|
||||||
|
: pkt(pkt), queryid(queryid), subid(subid)
|
||||||
|
{
|
||||||
|
timeout = time(NULL) + 5;
|
||||||
|
}
|
||||||
|
|
||||||
|
NetPkt* ModGameSpy1::merge(NetPkt* pkt, int queryid, int subid)
|
||||||
|
{
|
||||||
|
Iterator<MultiPart>* it = list.createIteratorRW();
|
||||||
|
|
||||||
|
NetPkt* tmppkt = new NetPkt(NULL, 0);
|
||||||
|
tmppkt->setAddress(pkt->getAddress());
|
||||||
|
|
||||||
|
bool found;
|
||||||
|
int searchid = 1;
|
||||||
|
do {
|
||||||
|
found = false;
|
||||||
|
while (it->hasNext()) {
|
||||||
|
MultiPart* mp = it->next();
|
||||||
|
if (!pkt->sameAddress(mp->pkt))
|
||||||
|
continue;
|
||||||
|
|
||||||
|
if (queryid != mp->queryid)
|
||||||
|
continue;
|
||||||
|
|
||||||
|
it->remove();
|
||||||
|
found = true;
|
||||||
|
|
||||||
|
if (searchid == mp->subid) {
|
||||||
|
tmppkt->append(mp->pkt);
|
||||||
|
searchid++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
it->reset();
|
||||||
|
} while (found && (searchid < subid));
|
||||||
|
|
||||||
|
delete it;
|
||||||
|
|
||||||
|
tmppkt->append(pkt);
|
||||||
|
delete pkt;
|
||||||
|
|
||||||
|
if (!found) {
|
||||||
|
delete tmppkt;
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
return tmppkt;
|
||||||
|
}
|
||||||
|
|
||||||
|
int ModGameSpy1::parse_real(NetPkt* pkt, GameList* glist, int gameid)
|
||||||
|
{
|
||||||
|
int port, offset, pos1, pos2;
|
||||||
|
|
||||||
|
pos1 = pkt->find(0, search_gamename, strlen(search_gamename));
|
||||||
|
pos1 += strlen(search_gamename);
|
||||||
|
|
||||||
|
switch (gameid) {
|
||||||
|
case ID_UT:
|
||||||
|
if (pkt->compare(pos1, reply_ut, strlen(reply_ut)))
|
||||||
|
gameid = ID_UT;
|
||||||
|
|
||||||
|
else if (pkt->compare(pos1, reply_ut2k3, strlen(reply_ut2k4)))
|
||||||
|
gameid = ID_UT2K3;
|
||||||
|
|
||||||
|
else if (pkt->compare(pos1, reply_ut2k4, strlen(reply_ut2k4)))
|
||||||
|
gameid = ID_UT2K4;
|
||||||
|
|
||||||
|
else if (pkt->compare(pos1, reply_aao, strlen(reply_aao)))
|
||||||
|
gameid = ID_AAO;
|
||||||
|
|
||||||
|
else if (pkt->compare(pos1, reply_postal2, strlen(reply_postal2)))
|
||||||
|
return PARSE_ACCEPT_FAKE;
|
||||||
|
|
||||||
|
else
|
||||||
|
return PARSE_REJECT;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case ID_BF1942:
|
||||||
|
case ID_BFV:
|
||||||
|
pos2 = pkt->find(0, search_gameid, strlen(search_gameid));
|
||||||
|
pos2 += strlen(search_gameid);
|
||||||
|
|
||||||
|
if (pkt->compare(pos1, reply_bf1942, strlen(reply_bf1942)))
|
||||||
|
gameid = ID_BF1942;
|
||||||
|
|
||||||
|
else if (pkt->compare(pos2, reply_bfv1, strlen(reply_bfv1)))
|
||||||
|
gameid = ID_BFV;
|
||||||
|
|
||||||
|
else if (pkt->compare(pos2, reply_bfv2, strlen(reply_bfv2)))
|
||||||
|
gameid = ID_BFV;
|
||||||
|
|
||||||
|
else if (pkt->compare(pos2, reply_poe, strlen(reply_poe)))
|
||||||
|
gameid = ID_BFV;
|
||||||
|
|
||||||
|
else if (pkt->compare(pos2, reply_opk, strlen(reply_opk)))
|
||||||
|
gameid = ID_BFV;
|
||||||
|
else
|
||||||
|
return PARSE_REJECT;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case ID_AVP2:
|
||||||
|
pos2 = pkt->find(0, search_gsgamename, strlen(search_gsgamename));
|
||||||
|
pos2 += strlen(search_gsgamename);
|
||||||
|
|
||||||
|
if (pkt->compare(pos1, reply_avp2, strlen(reply_avp2)))
|
||||||
|
gameid = ID_AVP2;
|
||||||
|
|
||||||
|
else if (pkt->compare(pos2, reply_fear, strlen(reply_fear)))
|
||||||
|
return PARSE_ACCEPT_FAKE;
|
||||||
|
|
||||||
|
else
|
||||||
|
return PARSE_REJECT;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case ID_RUNE:
|
||||||
|
if (pkt->compare(pos1, reply_rune, strlen(reply_rune)))
|
||||||
|
gameid = ID_RUNE;
|
||||||
|
else
|
||||||
|
return PARSE_REJECT;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case ID_IGI2:
|
||||||
|
if (pkt->compare(pos1, reply_igi2, strlen(reply_igi2)))
|
||||||
|
gameid = ID_IGI2;
|
||||||
|
else
|
||||||
|
return PARSE_REJECT;
|
||||||
|
break;
|
||||||
|
|
||||||
|
default:
|
||||||
|
return PARSE_REJECT;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* hostport angabe suchen */
|
||||||
|
offset = pkt->find(0, search_hostport, strlen(search_hostport));
|
||||||
|
if (offset != -1)
|
||||||
|
pkt->parse_int(offset + strlen(search_hostport), &port);
|
||||||
|
|
||||||
|
/*
|
||||||
|
* wenn ein hostport angegeben wurde, und das nicht der src port ist
|
||||||
|
* beide ports in die serverliste uebernehmen
|
||||||
|
*/
|
||||||
|
if ((offset != -1) && (port != pkt->getPort())) {
|
||||||
|
glist->addGame(gameid, pkt, port, true);
|
||||||
|
|
||||||
|
} else {
|
||||||
|
glist->addGame(gameid, pkt);
|
||||||
|
}
|
||||||
|
return PARSE_ACCEPT;
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,17 +1,36 @@
|
||||||
#ifndef _MODGAMESPY1_H_
|
#ifndef _MODGAMESPY1_H_
|
||||||
#define _MODGAMESPY1_H_
|
#define _MODGAMESPY1_H_
|
||||||
|
|
||||||
|
#include "list.h"
|
||||||
#include "module.h"
|
#include "module.h"
|
||||||
|
|
||||||
class ModGameSpy1 : public Module {
|
class ModGameSpy1 : public Module {
|
||||||
public:
|
public:
|
||||||
ModGameSpy1() {}
|
ModGameSpy1();
|
||||||
~ModGameSpy1() {}
|
~ModGameSpy1();
|
||||||
|
|
||||||
void scan(MultiSock* msock);
|
void scan(MultiSock* msock);
|
||||||
int parse(NetPkt* pkt, GameList* glist);
|
int parse(NetPkt* pkt, GameList* glist);
|
||||||
|
|
||||||
const char* getName() { return "GameSpy 1 Protocol"; }
|
const char* getName() { return "GameSpy 1 Protocol"; }
|
||||||
|
|
||||||
|
private:
|
||||||
|
class MultiPart {
|
||||||
|
public:
|
||||||
|
MultiPart(NetPkt* pkt, int queryid, int subid);
|
||||||
|
~MultiPart() {}
|
||||||
|
|
||||||
|
NetPkt* pkt;
|
||||||
|
int queryid;
|
||||||
|
int subid;
|
||||||
|
|
||||||
|
long timeout;
|
||||||
|
};
|
||||||
|
|
||||||
|
NetPkt* merge(NetPkt* pkt, int queryid, int subid);
|
||||||
|
int parse_real(NetPkt* pkt, GameList* glist, int gameid);
|
||||||
|
|
||||||
|
List<MultiPart> list;
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif // _MODGAMESPY1_H_
|
#endif // _MODGAMESPY1_H_
|
||||||
|
|
|
@ -1,25 +1,88 @@
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
|
#include "logging.h"
|
||||||
#include "modhelper.h"
|
#include "modhelper.h"
|
||||||
#include "mod_gamespy2.h"
|
#include "mod_gamespy2.h"
|
||||||
|
|
||||||
static struct game_ports port_arr[] = {
|
static struct game_ports port_arr[] = {
|
||||||
{ 7777, 7788, ID_UT }, // ut(5), ut2k3(14), rune(18), ut2k4(33), aao(15)
|
{ 2302, 2302, ID_HALO },
|
||||||
{ 22000, 22010, ID_BF1942 }, // bf1942(16)
|
{ 3455, 3455, ID_PK },
|
||||||
{ 23000, 23010, ID_BFV }, // bfv(35)
|
{ 10481, 10482, ID_SWAT4 },
|
||||||
{ 26001, 26011, ID_IGI2 }, // igi2(19)
|
{ 29900, 29910, ID_BF2 },
|
||||||
{ 27888, 27888, ID_AVP2 }, // avp2(17)
|
{ 0, 0, 0 }
|
||||||
{ 0,0,0 }
|
|
||||||
};
|
};
|
||||||
|
|
||||||
static const char scanmsg[] = { 0xFE, 0xFD, 0x00, 0xDE, 0xAD, 0xBE, 0xEF, 0xFF, 0x00, 0x00 };
|
static const char scanmsg[] = { 0xFE, 0xFD, 0x00, 0xDE, 0xAD, 0xBE, 0xEF, 0xFF, 0x00, 0x00 };
|
||||||
static const char replyhead[] = { 0x00, 0xDE, 0xAD, 0xBE, 0xEF };
|
static const char replyhead[] = { 0x00, 0xDE, 0xAD, 0xBE, 0xEF };
|
||||||
|
|
||||||
|
static const char search_hostport[] = "hostport";
|
||||||
|
static const char search_gamename[] = "gamename";
|
||||||
|
|
||||||
|
static const char reply_bf2[] = "battlefield2";
|
||||||
|
|
||||||
void ModGameSpy2::scan(MultiSock* msock)
|
void ModGameSpy2::scan(MultiSock* msock)
|
||||||
{
|
{
|
||||||
ModHelper::send(msock, port_arr, scanmsg, sizeof(scanmsg));
|
ModHelper::send(msock, port_arr, scanmsg, sizeof(scanmsg));
|
||||||
}
|
}
|
||||||
|
|
||||||
int ModGameSpy2::parse(NetPkt* pkt, GameList* slist)
|
int ModGameSpy2::parse(NetPkt* pkt, GameList* glist)
|
||||||
{
|
{
|
||||||
return 0;
|
int gameid, pos1, pos2, port;
|
||||||
|
|
||||||
|
gameid = ModHelper::checkPorts(pkt, port_arr);
|
||||||
|
if (!gameid)
|
||||||
|
return PARSE_REJECT;
|
||||||
|
|
||||||
|
if (!pkt->compare(0, replyhead, sizeof(replyhead)))
|
||||||
|
return PARSE_REJECT;
|
||||||
|
|
||||||
|
pos1 = pkt->find(0, search_gamename, strlen(search_gamename));
|
||||||
|
pos1 += strlen(search_gamename) +1;
|
||||||
|
|
||||||
|
/* hostport angabe suchen */
|
||||||
|
pos2 = pkt->find(0, search_hostport, strlen(search_hostport));
|
||||||
|
if (pos2 != -1) {
|
||||||
|
pos2 += strlen(search_hostport) +1;
|
||||||
|
pkt->parse_int(pos2, &port);
|
||||||
|
}
|
||||||
|
|
||||||
|
switch (gameid) {
|
||||||
|
case ID_HALO:
|
||||||
|
case ID_PK:
|
||||||
|
break;
|
||||||
|
|
||||||
|
case ID_SWAT4:
|
||||||
|
if (pos2 == -1)
|
||||||
|
return PARSE_REJECT;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case ID_BF2:/* battlefield 2 */
|
||||||
|
// TODO: pos2 check noetig?
|
||||||
|
if (pos2 == -1) {
|
||||||
|
LogSystem::log(LOG_DEBUG, "no hostport found");
|
||||||
|
return PARSE_REJECT;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (pkt->find(pos1, reply_bf2, strlen(reply_bf2)) == -1) {
|
||||||
|
LogSystem::log(LOG_DEBUG, "no gamename found");
|
||||||
|
return PARSE_REJECT;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
|
||||||
|
default:
|
||||||
|
return PARSE_REJECT;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* wenn ein hostport angegeben wurde, und das nicht der src port ist
|
||||||
|
* beide ports in die serverliste uebernehmen
|
||||||
|
*/
|
||||||
|
if ((pos2 != -1) && (port != pkt->getPort())) {
|
||||||
|
glist->addGame(gameid, pkt, port, true);
|
||||||
|
|
||||||
|
} else {
|
||||||
|
glist->addGame(gameid, pkt);
|
||||||
|
}
|
||||||
|
|
||||||
|
return PARSE_ACCEPT;
|
||||||
}
|
}
|
||||||
|
|
|
@ -11,6 +11,9 @@ static const char scanmsg1[] = "\xff\xff\xff\xff""details";
|
||||||
static const char scanmsg2[] = "\xff\xff\xff\xff\x54";
|
static const char scanmsg2[] = "\xff\xff\xff\xff\x54";
|
||||||
static const char scanmsg3[] = "\xff\xff\xff\xff""TSource Engine Query";
|
static const char scanmsg3[] = "\xff\xff\xff\xff""TSource Engine Query";
|
||||||
|
|
||||||
|
static const char reply1[] = "m\x00";
|
||||||
|
static const char reply2[] = "I\x07";
|
||||||
|
|
||||||
void ModHalfLife::scan(MultiSock* msock)
|
void ModHalfLife::scan(MultiSock* msock)
|
||||||
{
|
{
|
||||||
ModHelper::send(msock, port_arr, scanmsg1, strlen(scanmsg1));
|
ModHelper::send(msock, port_arr, scanmsg1, strlen(scanmsg1));
|
||||||
|
@ -18,7 +21,42 @@ void ModHalfLife::scan(MultiSock* msock)
|
||||||
ModHelper::send(msock, port_arr, scanmsg3, strlen(scanmsg3));
|
ModHelper::send(msock, port_arr, scanmsg3, strlen(scanmsg3));
|
||||||
}
|
}
|
||||||
|
|
||||||
int ModHalfLife::parse(NetPkt* pkt, GameList* slist)
|
int ModHalfLife::parse(NetPkt* pkt, GameList* glist)
|
||||||
{
|
{
|
||||||
return 0;
|
struct in_addr tmp;
|
||||||
|
int port, count, pos;
|
||||||
|
|
||||||
|
if (ModHelper::checkPorts(pkt, port_arr) == 0)
|
||||||
|
return PARSE_REJECT;
|
||||||
|
|
||||||
|
// check 0xFF 0xFF 0xFF 0xFF
|
||||||
|
if (!pkt->compare(0, scanmsg1, 4))
|
||||||
|
return PARSE_REJECT;
|
||||||
|
|
||||||
|
/* check for short answer without ip/port */
|
||||||
|
if (pkt->compare(4, reply1, 2)) {
|
||||||
|
glist->addGame(ID_HL, pkt);
|
||||||
|
return PARSE_ACCEPT;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* second query?! */
|
||||||
|
if (pkt->compare(4, reply2, 2)) {
|
||||||
|
glist->addGame(ID_HL2, pkt);
|
||||||
|
return PARSE_ACCEPT;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* parse server IP */
|
||||||
|
pos = 5;
|
||||||
|
if ((count = pkt->parse_ip(pos, &tmp)) == 0)
|
||||||
|
return PARSE_REJECT;
|
||||||
|
|
||||||
|
/* parse server port */
|
||||||
|
pos += count +1;
|
||||||
|
if ((count = pkt->parse_int(pos, &port)) == 0)
|
||||||
|
return PARSE_REJECT;
|
||||||
|
|
||||||
|
// TODO: check server IP?
|
||||||
|
//glist->add(ID_HL, &tmp, port, 0);
|
||||||
|
glist->addGame(ID_HL, pkt);
|
||||||
|
return PARSE_ACCEPT;
|
||||||
}
|
}
|
||||||
|
|
|
@ -3,10 +3,10 @@
|
||||||
#include "mod_q3engine.h"
|
#include "mod_q3engine.h"
|
||||||
|
|
||||||
static struct game_ports port_arr[] = {
|
static struct game_ports port_arr[] = {
|
||||||
{ 27960, 27960, ID_Q3A }, // q3(6), ef(7), et25), rtcw(8)
|
{ 27960, 27969, ID_Q3A }, // q3(6), ef(7), et25), rtcw(8)
|
||||||
// { 28070, 28070, ID_JK2 }, // jk2(12)
|
{ 28070, 28070, ID_JK2 }, // jk2(12)
|
||||||
// { 28960, 28963, ID_COD }, // cod(31), cod:uo(42), cod2(48)
|
{ 28960, 28963, ID_COD }, // cod(31), cod:uo(42), cod2(48)
|
||||||
// { 29070, 29070, ID_JK3 }, // jk3(27)
|
{ 29070, 29070, ID_JK3 }, // jk3(27)
|
||||||
{ 0,0,0 }
|
{ 0,0,0 }
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -108,6 +108,6 @@ int MultiSock::sendto(NetPkt* pkt, struct sockaddr_in* dst)
|
||||||
|
|
||||||
delete it;
|
delete it;
|
||||||
|
|
||||||
usleep(10000);
|
usleep(1000);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
141
netpkt.cpp
141
netpkt.cpp
|
@ -8,25 +8,26 @@
|
||||||
#include <net/if.h>
|
#include <net/if.h>
|
||||||
#include <netinet/in.h>
|
#include <netinet/in.h>
|
||||||
#include <arpa/inet.h>
|
#include <arpa/inet.h>
|
||||||
|
#include <ctype.h>
|
||||||
|
|
||||||
#include "logging.h"
|
#include "logging.h"
|
||||||
#include "module.h"
|
#include "module.h"
|
||||||
#include "netpkt.h"
|
#include "netpkt.h"
|
||||||
|
|
||||||
NetPkt::NetPkt(const char* data, int size)
|
NetPkt::NetPkt(const char* data, int size)
|
||||||
: data(data), used(size), size(0)
|
: data(data), size(size), alloc(0)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
NetPkt::NetPkt(int size)
|
NetPkt::NetPkt(int alloc)
|
||||||
: used(0), size(size)
|
: size(0), alloc(alloc)
|
||||||
{
|
{
|
||||||
data = new char[size];
|
data = new char[alloc];
|
||||||
}
|
}
|
||||||
|
|
||||||
NetPkt::~NetPkt()
|
NetPkt::~NetPkt()
|
||||||
{
|
{
|
||||||
if (size > 0)
|
if (alloc > 0)
|
||||||
delete data;
|
delete data;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -35,27 +36,23 @@ int NetPkt::show(char* buf, int size)
|
||||||
return snprintf(buf, size, "(%s:%d) (%d/%d) bytes",
|
return snprintf(buf, size, "(%s:%d) (%d/%d) bytes",
|
||||||
inet_ntoa(this->addr.sin_addr),
|
inet_ntoa(this->addr.sin_addr),
|
||||||
ntohs(this->addr.sin_port),
|
ntohs(this->addr.sin_port),
|
||||||
this->used, this->size);
|
this->size, this->alloc);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool NetPkt::compare(int offset, const char* buf, int len)
|
bool NetPkt::compare(unsigned int offset, const char* buf, unsigned int len)
|
||||||
{
|
{
|
||||||
if (offset >= this->used)
|
if (offset + len >= this->size)
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
/* nicht ueber das paket hinaus vergleichen */
|
|
||||||
if (offset + len >= this->used)
|
|
||||||
len = this->used - offset;
|
|
||||||
|
|
||||||
return (memcmp(this->data + offset, buf, len) == 0);
|
return (memcmp(this->data + offset, buf, len) == 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
int NetPkt::find(int offset, const char *buf, int len)
|
int NetPkt::find(unsigned int offset, const char *buf, unsigned int len)
|
||||||
{
|
{
|
||||||
if (offset >= this->used)
|
if (offset >= this->size)
|
||||||
return -1;
|
return -1;
|
||||||
|
|
||||||
void* found = memmem(this->data + offset, this->used, buf, len);
|
void* found = memmem(this->data + offset, this->size, buf, len);
|
||||||
|
|
||||||
return (found == NULL) ? -1 : ((char*)found - this->data);
|
return (found == NULL) ? -1 : ((char*)found - this->data);
|
||||||
}
|
}
|
||||||
|
@ -69,3 +66,117 @@ struct sockaddr_in * NetPkt::getAddress()
|
||||||
{
|
{
|
||||||
return &addr;
|
return &addr;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int NetPkt::parse_int(unsigned int offset, int *val)
|
||||||
|
{
|
||||||
|
const char *max = this->data + this->size;
|
||||||
|
const char *c = this->data + offset;
|
||||||
|
|
||||||
|
/* untere grenze abtesten */
|
||||||
|
if (this->data > c || c > max)
|
||||||
|
return -1;
|
||||||
|
|
||||||
|
*val = 0;
|
||||||
|
|
||||||
|
/* ziffern einlesen */
|
||||||
|
while (isdigit(*c) && c < max)
|
||||||
|
*val = (*val * 10) + (*c++ - 0x30);
|
||||||
|
|
||||||
|
return (c - (this->data + offset));
|
||||||
|
}
|
||||||
|
|
||||||
|
int NetPkt::parse_ip(unsigned int offset, struct in_addr *ip)
|
||||||
|
{
|
||||||
|
int i, tmp, count, pos = offset;
|
||||||
|
ip->s_addr = 0;
|
||||||
|
|
||||||
|
for (i = 0; i < 4; i++) {
|
||||||
|
count = this->parse_int(pos, &tmp);
|
||||||
|
pos += count;
|
||||||
|
if (count == 0 || tmp < 0 || tmp > 255)
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
ip->s_addr = ip->s_addr>>8 | tmp<<24;
|
||||||
|
|
||||||
|
if (i != 3 && this->data[pos++] != '.')
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
return pos - offset;
|
||||||
|
}
|
||||||
|
|
||||||
|
int NetPkt::getPort()
|
||||||
|
{
|
||||||
|
return ntohs(addr.sin_port);
|
||||||
|
}
|
||||||
|
|
||||||
|
char* NetPkt::showfull()
|
||||||
|
{
|
||||||
|
unsigned int pos = 0, i = 0, j;
|
||||||
|
char *buf = new char[this->size * 4 + 64];
|
||||||
|
|
||||||
|
while (pos < this->size) {
|
||||||
|
i += sprintf(buf + i, "%04X: ", pos);
|
||||||
|
for (j = 0; j < 16; j++) {
|
||||||
|
if (pos + j < this->size)
|
||||||
|
i += sprintf(buf + i, "%02X", (unsigned char)this->data[pos + j]);
|
||||||
|
else
|
||||||
|
i += sprintf(buf + i, " ");
|
||||||
|
|
||||||
|
if (j % 2)
|
||||||
|
buf[i++] = ' ';
|
||||||
|
}
|
||||||
|
|
||||||
|
for (j = 0; j < 16; j++) {
|
||||||
|
if (pos + j < this->size) {
|
||||||
|
unsigned char val = this->data[pos + j];
|
||||||
|
if (val >= 0x20 && val < 0x80)
|
||||||
|
buf[i++] = val;
|
||||||
|
else
|
||||||
|
buf[i++] = '.';
|
||||||
|
} else {
|
||||||
|
buf[i++] = ' ';
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pos += 16;
|
||||||
|
buf[i++] = '\r';
|
||||||
|
buf[i++] = '\n';
|
||||||
|
}
|
||||||
|
buf[i] = 0;
|
||||||
|
return buf;
|
||||||
|
}
|
||||||
|
|
||||||
|
int NetPkt::getSize()
|
||||||
|
{
|
||||||
|
return size;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool NetPkt::sameAddress(NetPkt* pkt)
|
||||||
|
{
|
||||||
|
return (this->addr.sin_addr.s_addr == pkt->addr.sin_addr.s_addr) &&
|
||||||
|
(this->addr.sin_port == pkt->addr.sin_port);
|
||||||
|
}
|
||||||
|
|
||||||
|
void NetPkt::append(NetPkt* pkt)
|
||||||
|
{
|
||||||
|
char buf1[64], buf2[64];
|
||||||
|
this->show(buf1, sizeof(buf1));
|
||||||
|
pkt->show(buf2, sizeof(buf2));
|
||||||
|
LogSystem::log(LOG_DEBUG, "append (%s) + (%s)", buf1, buf2);
|
||||||
|
|
||||||
|
unsigned int new_alloc = size + pkt->size;
|
||||||
|
|
||||||
|
char* new_data = new char[new_alloc];
|
||||||
|
memcpy(new_data, data, size);
|
||||||
|
|
||||||
|
if (alloc)
|
||||||
|
delete data;
|
||||||
|
|
||||||
|
data = new_data;
|
||||||
|
alloc = new_alloc;
|
||||||
|
|
||||||
|
memcpy((void*)(data + size), pkt->data, pkt->size);
|
||||||
|
size += pkt->size;
|
||||||
|
|
||||||
|
delete pkt;
|
||||||
|
}
|
||||||
|
|
23
netpkt.h
23
netpkt.h
|
@ -6,6 +6,8 @@
|
||||||
|
|
||||||
#define PARSE_ACCEPT 1
|
#define PARSE_ACCEPT 1
|
||||||
#define PARSE_ACCEPT_FREED 2
|
#define PARSE_ACCEPT_FREED 2
|
||||||
|
#define PARSE_ACCEPT_FAKE 3
|
||||||
|
#define PARSE_ACCEPT_QUIRK PARSE_ACCEPT
|
||||||
#define PARSE_REJECT 4
|
#define PARSE_REJECT 4
|
||||||
|
|
||||||
/* avoid cyclic deps */
|
/* avoid cyclic deps */
|
||||||
|
@ -15,15 +17,26 @@ class NetPkt {
|
||||||
friend class Socket;
|
friend class Socket;
|
||||||
public:
|
public:
|
||||||
NetPkt(const char* data, int size);
|
NetPkt(const char* data, int size);
|
||||||
NetPkt(int size);
|
NetPkt(int alloc);
|
||||||
~NetPkt();
|
~NetPkt();
|
||||||
|
|
||||||
int show(char* buf, int size);
|
int show(char* buf, int size);
|
||||||
bool compare(int offset, const char* buf, int len);
|
char* showfull();
|
||||||
int find(int offset, const char *buf, int len);
|
|
||||||
|
bool compare(unsigned int offset, const char* buf, unsigned int len);
|
||||||
|
int find(unsigned int offset, const char *buf, unsigned int len);
|
||||||
|
|
||||||
|
int parse_int(unsigned int offset, int *val);
|
||||||
|
int parse_ip(unsigned int offset, struct in_addr *ip);
|
||||||
|
|
||||||
void setAddress(struct sockaddr_in *addr);
|
void setAddress(struct sockaddr_in *addr);
|
||||||
struct sockaddr_in * getAddress();
|
struct sockaddr_in * getAddress();
|
||||||
|
bool sameAddress(NetPkt* pkt);
|
||||||
|
|
||||||
|
void append(NetPkt* pkt);
|
||||||
|
|
||||||
|
int getPort();
|
||||||
|
int getSize();
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
NetPkt(const NetPkt& x);
|
NetPkt(const NetPkt& x);
|
||||||
|
@ -31,10 +44,10 @@ protected:
|
||||||
|
|
||||||
struct sockaddr_in addr;
|
struct sockaddr_in addr;
|
||||||
const char *data;
|
const char *data;
|
||||||
int used;
|
unsigned int size;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
int size;
|
unsigned int alloc;
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif // _NETPKT_H_
|
#endif // _NETPKT_H_
|
||||||
|
|
|
@ -155,7 +155,7 @@ int Socket::sendto(NetPkt* pkt, struct sockaddr_in* dst) {
|
||||||
if (!dst)
|
if (!dst)
|
||||||
dst = &pkt->addr;
|
dst = &pkt->addr;
|
||||||
|
|
||||||
if (::sendto(fd, pkt->data, pkt->used, 0, (struct sockaddr *)dst, sizeof(*dst)) < 0)
|
if (::sendto(fd, pkt->data, pkt->size, 0, (struct sockaddr *)dst, sizeof(*dst)) < 0)
|
||||||
LogSystem::log(LOG_WARN, "Socket::sendto()");
|
LogSystem::log(LOG_WARN, "Socket::sendto()");
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
@ -169,7 +169,7 @@ NetPkt* Socket::recv() {
|
||||||
|
|
||||||
NetPkt* pkt = new NetPkt(this->getRecvSize());
|
NetPkt* pkt = new NetPkt(this->getRecvSize());
|
||||||
socklen_t i = sizeof(pkt->addr);
|
socklen_t i = sizeof(pkt->addr);
|
||||||
pkt->used = ::recvfrom(fd, (void*)pkt->data, pkt->size, 0, (struct sockaddr *)&pkt->addr, &i);
|
pkt->size = ::recvfrom(fd, (void*)pkt->data, pkt->alloc, 0, (struct sockaddr *)&pkt->addr, &i);
|
||||||
|
|
||||||
return pkt;
|
return pkt;
|
||||||
}
|
}
|
||||||
|
|
|
@ -2,6 +2,8 @@
|
||||||
|
|
||||||
#include "timerservice.h"
|
#include "timerservice.h"
|
||||||
|
|
||||||
|
// TODO: how to deregister TimerEvents?
|
||||||
|
|
||||||
Timer::Timer(Event* event, unsigned int timeval)
|
Timer::Timer(Event* event, unsigned int timeval)
|
||||||
: next(0), event(event), timeval(timeval)
|
: next(0), event(event), timeval(timeval)
|
||||||
{
|
{
|
||||||
|
|
Loading…
Reference in New Issue