From: <f-r...@us...> - 2011-02-12 21:06:44
|
Revision: 244 http://netemul.svn.sourceforge.net/netemul/?rev=244&view=rev Author: f-r-o-s-t Date: 2011-02-12 21:06:36 +0000 (Sat, 12 Feb 2011) Log Message: ----------- All troubles of last revision are resolved, dhcp program works Modified Paths: -------------- trunk/src/deviceport.cpp trunk/src/dialogs/dhcpserverproperty.cpp trunk/src/dialogs/programdialog.cpp trunk/src/dialogs/programdialog.h trunk/src/forms/programdialog.ui trunk/src/programs/dhcpserverprogram.cpp trunk/src/programs/dhcpserverprogram.h trunk/src/programs/programs.pri Added Paths: ----------- trunk/src/programs/dhcpdaemon.cpp trunk/src/programs/dhcpdaemon.h Removed Paths: ------------- trunk/src/programs/dhcpdemon.cpp trunk/src/programs/dhcpdemon.h Modified: trunk/src/deviceport.cpp =================================================================== --- trunk/src/deviceport.cpp 2011-02-11 23:05:12 UTC (rev 243) +++ trunk/src/deviceport.cpp 2011-02-12 21:06:36 UTC (rev 244) @@ -21,7 +21,7 @@ #include "cabledev.h" #include "frame.h" -DevicePort::DevicePort(QObject *parent) +DevicePort::DevicePort(QObject *parent) :QObject(parent) { myShared = false; myCable = 0; Modified: trunk/src/dialogs/dhcpserverproperty.cpp =================================================================== --- trunk/src/dialogs/dhcpserverproperty.cpp 2011-02-11 23:05:12 UTC (rev 243) +++ trunk/src/dialogs/dhcpserverproperty.cpp 2011-02-12 21:06:36 UTC (rev 244) @@ -135,11 +135,11 @@ return; } myDaemon->setTurnOn(cb_turnOn->isChecked()); - myDaemon->setBeginIp(ie_begin->ipAddress()); - myDaemon->setEndIp(ie_end->ipAddress()); + myDaemon->setBeginIp(ie_begin->ipText()); + myDaemon->setEndIp(ie_end->ipText()); myDaemon->setDynamic(cb_dynamic->isChecked()); - myDaemon->setGateway(ie_gatew->ipAddress()); - myDaemon->setMask(ie_mask->ipAddress()); + myDaemon->setGateway(ie_gatew->ipText()); + myDaemon->setMask(ie_mask->ipText()); myDaemon->setTime(sb_time->value()); myDaemon->setWaitingTime(sb_waitingTime->value()); } Modified: trunk/src/dialogs/programdialog.cpp =================================================================== --- trunk/src/dialogs/programdialog.cpp 2011-02-11 23:05:12 UTC (rev 243) +++ trunk/src/dialogs/programdialog.cpp 2011-02-12 21:06:36 UTC (rev 244) @@ -17,12 +17,12 @@ ** Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA ** 02111-1307 USA. ****************************************************************************************/ -#include "programmdialog.h" +#include "programdialog.h" #include "smartdevice.h" #include "installdialog.h" #include <QCheckBox> -programmDialog::programmDialog(QWidget *parent) : QDialog(parent) +ProgramDialog::ProgramDialog(QWidget *parent) : QDialog(parent) { setupUi(this); setAttribute(Qt::WA_DeleteOnClose); @@ -31,7 +31,7 @@ /*! Обновляет список программ. */ -void programmDialog::updateList() +void ProgramDialog::updateList() { list->clear(); foreach ( Program *i, s->programs() ){ @@ -44,13 +44,13 @@ } } //------------------------------------------------- -void programmDialog::programmChanged() +void ProgramDialog::programmChanged() { btn_remove->setEnabled( list->currentItem() ); btn_settings->setEnabled( list->currentItem() ); } -void programmDialog::stateChanged(QListWidgetItem *item) +void ProgramDialog::stateChanged(QListWidgetItem *item) { if ( !item ) return; Program *p = s->programAt( item->data( Qt::UserRole).toInt() ); @@ -58,7 +58,7 @@ p->updateView(); } -void programmDialog::setDevice( SmartDevice *d ) +void ProgramDialog::setDevice( SmartDevice *d ) { s = d; updateList(); @@ -67,7 +67,7 @@ Слот, вызываемый при нажатии на кнопку Ok, выполняет все принятые изменения, закрывает диалог. */ -void programmDialog::apply() +void ProgramDialog::apply() { for ( int i = 0; i < list->count(); i++) { QListWidgetItem *n = list->item(i); @@ -81,7 +81,7 @@ Слот вызывает диалог установки программ, обновляет список установленных программ. */ -void programmDialog::add() +void ProgramDialog::add() { installDialog *d = new installDialog; d->setDevice( s ); @@ -93,20 +93,20 @@ /*! Слот удаляет выделенную программу. */ -void programmDialog::remove() +void ProgramDialog::remove() { QListWidgetItem *w = list->currentItem(); s->removeProgram( s->programAt(w->data(Qt::UserRole).toInt() ) ); updateList(); } -void programmDialog::settings() +void ProgramDialog::settings() { s->programAt( list->currentItem()->data(Qt::UserRole).toInt() )->showProperty(); } //----------------------------------------------------- -void programmDialog::changeEvent(QEvent *e) +void ProgramDialog::changeEvent(QEvent *e) { QDialog::changeEvent(e); switch (e->type()) { Modified: trunk/src/dialogs/programdialog.h =================================================================== --- trunk/src/dialogs/programdialog.h 2011-02-11 23:05:12 UTC (rev 243) +++ trunk/src/dialogs/programdialog.h 2011-02-12 21:06:36 UTC (rev 244) @@ -27,11 +27,12 @@ /*! Реализует диалог установленных пограмм устройства. */ -class programmDialog : public QDialog, private Ui::programmDialog { +class ProgramDialog : public QDialog, private Ui::ProgramDialog +{ Q_OBJECT - Q_DISABLE_COPY(programmDialog) + Q_DISABLE_COPY(ProgramDialog) public: - programmDialog(QWidget *parent = 0); + ProgramDialog(QWidget *parent = 0); void setDevice( SmartDevice *d ); protected: void updateList(); Modified: trunk/src/forms/programdialog.ui =================================================================== --- trunk/src/forms/programdialog.ui 2011-02-11 23:05:12 UTC (rev 243) +++ trunk/src/forms/programdialog.ui 2011-02-12 21:06:36 UTC (rev 244) @@ -1,7 +1,7 @@ <?xml version="1.0" encoding="UTF-8"?> <ui version="4.0"> - <class>programmDialog</class> - <widget class="QDialog" name="programmDialog"> + <class>ProgramDialog</class> + <widget class="QDialog" name="ProgramDialog"> <property name="geometry"> <rect> <x>0</x> @@ -60,7 +60,7 @@ <string>Add</string> </property> <property name="icon"> - <iconset> + <iconset resource="../../netemul.qrc"> <normaloff>:/im/images/edit_add.png</normaloff>:/im/images/edit_add.png</iconset> </property> </widget> @@ -74,7 +74,7 @@ <string>Settings</string> </property> <property name="icon"> - <iconset> + <iconset resource="../../netemul.qrc"> <normaloff>:/im/images/setting.png</normaloff>:/im/images/setting.png</iconset> </property> </widget> @@ -88,7 +88,7 @@ <string>Delete</string> </property> <property name="icon"> - <iconset> + <iconset resource="../../netemul.qrc"> <normaloff>:/im/images/edit_remove.png</normaloff>:/im/images/edit_remove.png</iconset> </property> </widget> @@ -112,7 +112,7 @@ <string>Ok</string> </property> <property name="icon"> - <iconset> + <iconset resource="../../netemul.qrc"> <normaloff>:/im/images/ok.png</normaloff>:/im/images/ok.png</iconset> </property> </widget> @@ -123,7 +123,7 @@ <string>Cancel</string> </property> <property name="icon"> - <iconset> + <iconset resource="../../netemul.qrc"> <normaloff>:/im/images/not.png</normaloff>:/im/images/not.png</iconset> </property> </widget> @@ -134,12 +134,14 @@ </item> </layout> </widget> - <resources/> + <resources> + <include location="../../netemul.qrc"/> + </resources> <connections> <connection> <sender>btn_cancel</sender> <signal>clicked()</signal> - <receiver>programmDialog</receiver> + <receiver>ProgramDialog</receiver> <slot>reject()</slot> <hints> <hint type="sourcelabel"> @@ -155,7 +157,7 @@ <connection> <sender>btn_ok</sender> <signal>clicked()</signal> - <receiver>programmDialog</receiver> + <receiver>ProgramDialog</receiver> <slot>apply()</slot> <hints> <hint type="sourcelabel"> @@ -171,7 +173,7 @@ <connection> <sender>btn_add</sender> <signal>clicked()</signal> - <receiver>programmDialog</receiver> + <receiver>ProgramDialog</receiver> <slot>add()</slot> <hints> <hint type="sourcelabel"> @@ -187,7 +189,7 @@ <connection> <sender>btn_remove</sender> <signal>clicked()</signal> - <receiver>programmDialog</receiver> + <receiver>ProgramDialog</receiver> <slot>remove()</slot> <hints> <hint type="sourcelabel"> @@ -203,7 +205,7 @@ <connection> <sender>btn_settings</sender> <signal>clicked()</signal> - <receiver>programmDialog</receiver> + <receiver>ProgramDialog</receiver> <slot>settings()</slot> <hints> <hint type="sourcelabel"> @@ -219,7 +221,7 @@ <connection> <sender>list</sender> <signal>currentRowChanged(int)</signal> - <receiver>programmDialog</receiver> + <receiver>ProgramDialog</receiver> <slot>programmChanged()</slot> <hints> <hint type="sourcelabel"> @@ -235,7 +237,7 @@ <connection> <sender>list</sender> <signal>itemClicked(QListWidgetItem*)</signal> - <receiver>programmDialog</receiver> + <receiver>ProgramDialog</receiver> <slot>stateChanged(QListWidgetItem*)</slot> <hints> <hint type="sourcelabel"> Copied: trunk/src/programs/dhcpdaemon.cpp (from rev 243, trunk/src/programs/dhcpdemon.cpp) =================================================================== --- trunk/src/programs/dhcpdaemon.cpp (rev 0) +++ trunk/src/programs/dhcpdaemon.cpp 2011-02-12 21:06:36 UTC (rev 244) @@ -0,0 +1,254 @@ +#include "dhcpdaemon.h" +#include "interface.h" +#include "udppacket.h" +#include "dhcppacket.h" +#include "dhcpservermodel.h" + +void DhcpDaemon::setInterface(Interface *inter) +{ + myInterface = inter; + connect(myInterface, SIGNAL(receivedPacket(IpPacket)), SLOT(execute(IpPacket))); +} + +DhcpDaemon::DhcpDaemon(QObject *parent) : QObject(parent) +{ + myInterface = 0; + initialize(); +} + +DhcpDaemon::DhcpDaemon(Interface *inter, QObject *parent) : QObject(parent) +{ + setInterface(inter); + myInterfaceName = inter->name(); + myDhcpModel = new DhcpServerModel(this); + initialize(); +} + +DhcpDaemon::~DhcpDaemon() { + delete myDhcpModel; + clients.clear(); +} + +void DhcpDaemon::initialize() +{ + myDynamic = false; + myTime = 300; + myWaitingTime = 60; +} + +void DhcpDaemon::executeDiscover(DhcpPacket packet) +{ + ClientState *client = findClient( packet.xid() ); + if ( client && client->state == ClientState::IN_USE ) return; + client = chooseStatic(packet); + if ( client ) { + makeAnswer(client, DhcpPacket::DHCPOFFER); + return; + } + if ( !myDynamic ) return; + client = chooseDynamic(packet); + if ( client ) makeAnswer(client,DhcpPacket::DHCPOFFER); +} + +void DhcpDaemon::executeRequest(DhcpPacket packet) +{ + ClientState *client = findClient( packet.xid() ); + if ( !client ) return; + if ( packet.siaddr() != myInterface->ip() ) { + clients.removeOne(client); + delete client; + return; + } + makeAnswer( client, DhcpPacket::DHCPACK ); +} + +void DhcpDaemon::executeDecline(DhcpPacket packet) +{ + ClientState *client = findClient(packet.yiaddr()); + if ( !client ) return; + client->state = ClientState::DECLINE; +} + +ClientState* DhcpDaemon::chooseStatic(DhcpPacket packet) +{ + StaticDhcpRecord *rec = myDhcpModel->recordWithMac(packet.chaddr()); + if ( !rec ) return 0; + ClientState *client = new ClientState(rec); + if ( findClient(client->ip) ) return 0; + client->requestTimer = 0; + client->xid = packet.xid(); + clients << client; + return client; +} + +/*! + Выбираем адрес из динамического диапазона. + @return указатель на созданную запись. + */ +ClientState* DhcpDaemon::chooseDynamic(DhcpPacket packet) +{ + ClientState *cl = new ClientState; + cl->requestTimer = 0; + ClientState *c = findClient(packet.yiaddr()); + if ( !packet.yiaddr().isEmpty() && !c ) cl->ip = packet.yiaddr(); + else cl->ip = giveDynamicIp(); + if ( cl->ip.isEmpty() ) return NULL; + cl->mac = packet.chaddr(); + cl->xid = packet.xid(); + cl->time = myTime; + cl->mask = myMask; + cl->gateway = myGateway; + clients << cl; + return cl; +} + +/*! + Создаем dhcp пакет. + @param client - запись клиента на основе которой будем создавать пакет. + @param state - тип отправляемого сообщения. + @return созданный пакет. + */ +DhcpPacket DhcpDaemon::createDhcpPacket( ClientState *client, int state ) const +{ + if ( state == DhcpPacket::DHCPOFFER ) client->state = ClientState::WAIT_REQUEST; + else client->state = ClientState::IN_USE; + DhcpPacket p; + p.setType( state ); + p.setXid( client->xid ); + p.setChaddr( client->mac ); + p.setYiaddr( client->ip ); + p.setMask( client->mask ); + p.setGateway( client->gateway ); + p.setSiaddr( myInterface->ip() ); + p.setTime( client->time ); + return p; +} +//------------------------------------------------------------ + +void DhcpDaemon::sendDhcp(DhcpPacket packet) const +{ + UdpPacket udp; + udp.setSender( SERVER_SOCKET ); + udp.setReceiver( CLIENT_SOCKET ); + udp.pack( packet.toData() ); + IpPacket p( myInterface->ip(), IpAddress::full() ); + p.pack( udp.toData() ); + p.setUpProtocol( IpPacket::udp ); + myInterface->sendPacket(p); +} + +void DhcpDaemon::makeAnswer(ClientState *client, int type) +{ + DhcpPacket dhcp = createDhcpPacket(client,type); + sendDhcp(dhcp); +} + +/*! Ищет в списке клиента с данным идентификатрором и проверкой состояния записи. + @param xid - идентификатрор. + @return указатель на запись из списка, если xid совпали, или 0 в противном случае. + */ +ClientState* DhcpDaemon::findClient(int xid) const +{ + foreach ( ClientState *i, clients ) + if ( i->xid == xid && i->state != ClientState::DECLINE ) return i; + return 0; +} +//------------------------------------------------------------ +/*! Ищет в списке клиента с данным ip-адресом. + @param ip - адрес. + @return указатель на запись из списка, если ip совпали, или 0 в противном случае. + */ +ClientState* DhcpDaemon::findClient(IpAddress ip) const +{ + foreach ( ClientState *i, clients ) + if ( i->ip == ip ) return i; + return 0; +} +//-------------------------------------------------------------- +/*! + Выбирает ip-адрес из динамического диапазона + @return выбранный адрес, или "0.0.0.0", если нет свободных адресов. + */ +IpAddress DhcpDaemon::giveDynamicIp() const +{ + bool isContains = false; + quint32 i = myBeginIp.toInt(); + while ( i <= myEndIp.toInt() ) { + isContains = myDhcpModel->containRecord( IpAddress(i) ) || findClient(IpAddress(i)) + || myInterface->ip().toInt() == i; + if ( isContains ) { + i++; + isContains = false; + } + else { + return IpAddress(i); + } + } + return IpAddress("0.0.0.0"); +} +//------------------------------------------------------------- +void DhcpDaemon::incTime() { + bool canDelete = false; + foreach ( ClientState *i, clients ) { + if ( i->state == ClientState::WAIT_REQUEST ) { + if ( ++i->requestTimer == myWaitingTime ) canDelete = true; + } + else if ( i->state == ClientState::IN_USE && --i->time == 0 ) canDelete = true; + if ( canDelete ) { + canDelete = false; + clients.removeOne(i); + delete i; + } + } +} + +void DhcpDaemon::addDhcpServerModel(DhcpServerModel *model) +{ + myDhcpModel = model; +} + +//--------------------Public slots------------------ +void DhcpDaemon::execute(IpPacket p) +{ + if ( !isTurnOn() ) return; + if ( p.receiverSocket() == DhcpDaemon::SERVER_SOCKET ) { + UdpPacket u( p.unpack() ); + DhcpPacket d(u.unpack()); + switch ( d.type() ) { + case DhcpPacket::DHCPDISCOVER : + executeDiscover(d); + break; + case DhcpPacket::DHCPREQUEST : + executeRequest(d); + break; + case DhcpPacket::DHCPDECLINE : + executeDecline(d); + break; + } + } +} + +//-------------------------------------------------- + + +void DhcpDaemon::read(QDataStream &stream) +{ + stream >> myInterfaceName; + stream >> myBeginIp; + stream >> myEndIp; + stream >> myMask; + stream >> myGateway; + stream >> myTime; + stream >> myDynamic; + stream >> myWaitingTime; +} + +//----------------------------------------------------------------- +ClientState::ClientState(StaticDhcpRecord *rec) +{ + ip = rec->yiaddr; + mac = rec->chaddr; + mask = rec->mask; + gateway = rec->gateway; + time = rec->time; +} Copied: trunk/src/programs/dhcpdaemon.h (from rev 243, trunk/src/programs/dhcpdemon.h) =================================================================== --- trunk/src/programs/dhcpdaemon.h (rev 0) +++ trunk/src/programs/dhcpdaemon.h 2011-02-12 21:06:36 UTC (rev 244) @@ -0,0 +1,115 @@ +#ifndef DHCPDEMON_H +#define DHCPDEMON_H + +#include "ipaddress.h" +#include "macaddress.h" +#include "ippacket.h" + +class UdpSocket; +class DhcpPacket; +class Interface; +class StaticDhcpRecord; +class DhcpServerModel; + +struct ClientState { + int xid; + int state; + MacAddress mac; + IpAddress ip; + IpAddress mask; + IpAddress gateway; + int time; + int requestTimer; + enum { WAIT_REQUEST = 0, IN_USE = 1, DECLINE = 2 }; + ClientState(StaticDhcpRecord *rec); + ClientState() { } +}; + +class DhcpDaemon : public QObject +{ + Q_OBJECT + Q_PROPERTY( QString interfaceName READ interfaceName WRITE setInterfaceName ) + Q_PROPERTY( QString beginIp READ beginIp WRITE setBeginIp ) + Q_PROPERTY( QString endIp READ endIp WRITE setEndIp ) + Q_PROPERTY( QString mask READ mask WRITE setMask ) + Q_PROPERTY( QString gateway READ gateway WRITE setGateway ) + Q_PROPERTY( int time READ time WRITE setTime ) + Q_PROPERTY( int waitingTime READ waitingTime WRITE setWaitingTime ) + Q_PROPERTY( bool dynamic READ dynamic WRITE setDynamic ) + Q_PROPERTY( bool turnOn READ isTurnOn WRITE setTurnOn ) +public: + enum { CLIENT_SOCKET = 67 , SERVER_SOCKET = 68 }; + + DhcpDaemon(QObject* parent = 0); + DhcpDaemon(Interface *inter, QObject* parent = 0); + ~DhcpDaemon(); + void setInterface(Interface *inter); + void setInterfaceName(const QString &inter) { myInterfaceName = inter; } + void setBeginIp(const QString &ip) { myBeginIp.setIp(ip); } + void setEndIp(const QString &ip) { myEndIp.setIp(ip); } + void setMask(const QString &ip) { myMask.setIp(ip); } + void setGateway(const QString &ip) { myGateway.setIp(ip); } + void setTime(int t) { myTime = t; } + void setWaitingTime(int t) { myWaitingTime = t; } + void setDynamic(bool b) { myDynamic = b; } + void setTurnOn(bool b) { myTurnOn = b; } + Interface* interface() const { return myInterface; } + QString interfaceName() const { return myInterfaceName; } + QString beginIp() const { return myBeginIp.toString(); } + QString endIp() const { return myEndIp.toString(); } + QString mask() const { return myMask.toString(); } + QString gateway() const { return myGateway.toString(); } + int time() const { return myTime; } + int waitingTime() const { return myWaitingTime; } + bool dynamic() const { return myDynamic; } + bool isTurnOn() const { return myTurnOn; } + DhcpServerModel* dhcpModel() { return myDhcpModel; } + void incTime(); + IpAddress giveDynamicIp() const; + + void read(QDataStream &stream); + + Q_INVOKABLE void addDhcpServerModel(DhcpServerModel *model); + +// Обработка пакетов +public: + void executeDiscover(DhcpPacket packet); + void executeRequest(DhcpPacket packet); + void executeDecline(DhcpPacket packet); + +public slots: + void execute(IpPacket p); + +// Функция инициализации для конструкторов +private: + void initialize(); + +// Функции создания и отправки ответа +private: + void makeAnswer(ClientState* client, int type); + void sendDhcp(DhcpPacket packet) const; + DhcpPacket createDhcpPacket(ClientState *client, int state) const; + +// Функции выбора и нахождения записи клиента +private: + ClientState* chooseStatic(DhcpPacket packet); + ClientState* chooseDynamic(DhcpPacket packet); + ClientState* findClient( int xid ) const; + ClientState* findClient(IpAddress ip) const; + +private: + QList<ClientState*> clients; + Interface *myInterface; + QString myInterfaceName; + DhcpServerModel *myDhcpModel; + IpAddress myBeginIp; + IpAddress myEndIp; + IpAddress myMask; + IpAddress myGateway; + int myTime; + int myWaitingTime; + bool myDynamic; + bool myTurnOn; +}; + +#endif // DHCPDEMON_H Deleted: trunk/src/programs/dhcpdemon.cpp =================================================================== --- trunk/src/programs/dhcpdemon.cpp 2011-02-11 23:05:12 UTC (rev 243) +++ trunk/src/programs/dhcpdemon.cpp 2011-02-12 21:06:36 UTC (rev 244) @@ -1,207 +0,0 @@ -#include "dhcpdemon.h" -#include "interface.h" -#include "udppacket.h" -#include "dhcppacket.h" -#include "dhcpservermodel.h" - -DhcpDemon::DhcpDemon(QObject *parent) : QObject(parent) -{ - initialize(); -} - -DhcpDemon::DhcpDemon(Interface *inter) { - myInterface = inter->name(); - initialize(); -} - -DhcpDemon::~DhcpDemon() { - delete myDhcpModel; - //delete receiver; - clients.clear(); -} - -void DhcpDemon::executeDiscover(DhcpPacket packet) -{ - ClientState *client = findClient( packet.xid() ); - if ( client && client->state == ClientState::IN_USE ) return; - client = chooseStatic(packet); - if ( client ) { - makeAnswer(client, DhcpPacket::DHCPOFFER); - return; - } - if ( !myDynamic ) return; - client = chooseDynamic(packet); - if ( client ) makeAnswer(client,DhcpPacket::DHCPOFFER); -} - -void DhcpDemon::executeRequest(DhcpPacket packet) -{ - ClientState *client = findClient( packet.xid() ); - if ( !client ) return; -// if ( packet.siaddr() != myDevice->adapter(myInterface)->ip() ) { -// clients.removeOne(client); -// delete client; -// return; -// } - makeAnswer( client, DhcpPacket::DHCPACK ); -} - -void DhcpDemon::executeDecline(DhcpPacket packet) -{ - ClientState *client = findClient(packet.yiaddr()); - if ( !client ) return; - client->state = ClientState::DECLINE; -} - -void DhcpDemon::initialize() -{ - myDhcpModel = new DhcpServerModel; - myDynamic = false; - myTime = 300; - myWaitingTime = 60; -} - -ClientState* DhcpDemon::chooseStatic(DhcpPacket packet) -{ - StaticDhcpRecord *rec = myDhcpModel->recordWithMac(packet.chaddr()); - if ( !rec ) return 0; - ClientState *client = new ClientState(rec); - if ( findClient(client->ip) ) return 0; - client->requestTimer = 0; - client->xid = packet.xid(); - clients << client; - return client; -} - -/*! - Выбираем адрес из динамического диапазона. - @return указатель на созданную запись. - */ -ClientState* DhcpDemon::chooseDynamic(DhcpPacket packet) -{ - ClientState *cl = new ClientState; - cl->requestTimer = 0; - ClientState *c = findClient(packet.yiaddr()); - if ( !packet.yiaddr().isEmpty() && !c ) cl->ip = packet.yiaddr(); - else cl->ip = giveDynamicIp(); - if ( cl->ip.isEmpty() ) return NULL; - cl->mac = packet.chaddr(); - cl->xid = packet.xid(); - cl->time = myTime; - cl->mask = myMask; - cl->gateway = myGateway; - clients << cl; - return cl; -} - -/*! - Создаем dhcp пакет. - @param client - запись клиента на основе которой будем создавать пакет. - @param state - тип отправляемого сообщения. - @return созданный пакет. - */ -DhcpPacket DhcpDemon::createDhcpPacket( ClientState *client, int state ) const -{ - if ( state == DhcpPacket::DHCPOFFER ) client->state = ClientState::WAIT_REQUEST; - else client->state = ClientState::IN_USE; - DhcpPacket p; - p.setType( state ); - p.setXid( client->xid ); - p.setChaddr( client->mac ); - p.setYiaddr( client->ip ); - p.setMask( client->mask ); - p.setGateway( client->gateway ); - //p.setSiaddr( myDevice->adapter(myInterface)->ip() ); - p.setTime( client->time ); - return p; -} -//------------------------------------------------------------ - -void DhcpDemon::sendDhcp(DhcpPacket packet) const -{ - UdpPacket udp; - udp.setSender( SERVER_SOCKET ); - udp.setReceiver( CLIENT_SOCKET ); - udp.pack( packet.toData() ); - //ipPacket p( myDevice->adapter(myInterface)->ip(), ipAddress::full() ); - //p.pack( udp.toData() ); - //p.setUpProtocol( ipPacket::udp ); - //myDevice->adapter(myInterface)->sendPacket(p); -} - -void DhcpDemon::makeAnswer(ClientState *client, int type) -{ - DhcpPacket dhcp = createDhcpPacket(client,type); - sendDhcp(dhcp); -} - -/*! Ищет в списке клиента с данным идентификатрором и проверкой состояния записи. - @param xid - идентификатрор. - @return указатель на запись из списка, если xid совпали, или 0 в противном случае. - */ -ClientState* DhcpDemon::findClient(int xid) const -{ - foreach ( ClientState *i, clients ) - if ( i->xid == xid && i->state != ClientState::DECLINE ) return i; - return 0; -} -//------------------------------------------------------------ -/*! Ищет в списке клиента с данным ip-адресом. - @param ip - адрес. - @return указатель на запись из списка, если ip совпали, или 0 в противном случае. - */ -ClientState* DhcpDemon::findClient(IpAddress ip) const -{ - foreach ( ClientState *i, clients ) - if ( i->ip == ip ) return i; - return 0; -} -//-------------------------------------------------------------- -/*! - Выбирает ip-адрес из динамического диапазона - @return выбранный адрес, или "0.0.0.0", если нет свободных адресов. - */ -IpAddress DhcpDemon::giveDynamicIp() const -{ - bool isContains = false; - quint32 i = myBeginIp.toInt(); - while ( i <= myEndIp.toInt() ) { -// isContains = myDhcpModel->containRecord( ipAddress(i) ) || findClient(ipAddress(i)) -// || myDevice->adapter(myInterface)->ip().toInt() == i; - if ( isContains ) { - i++; - isContains = false; - } - else { - return IpAddress(i); - } - } - return IpAddress("0.0.0.0"); -} -//------------------------------------------------------------- -void DhcpDemon::incTime() { - bool canDelete = false; - foreach ( ClientState *i, clients ) { - if ( i->state == ClientState::WAIT_REQUEST ) { - if ( ++i->requestTimer == myWaitingTime ) canDelete = true; - } - else if ( i->state == ClientState::IN_USE && --i->time == 0 ) canDelete = true; - if ( canDelete ) { - canDelete = false; - clients.removeOne(i); - delete i; - } - } -} - -void DhcpDemon::read(QDataStream &stream) -{ - stream >> myInterface; - stream >> myBeginIp; - stream >> myEndIp; - stream >> myMask; - stream >> myGateway; - stream >> myTime; - stream >> myDynamic; - stream >> myWaitingTime; -} Deleted: trunk/src/programs/dhcpdemon.h =================================================================== --- trunk/src/programs/dhcpdemon.h 2011-02-11 23:05:12 UTC (rev 243) +++ trunk/src/programs/dhcpdemon.h 2011-02-12 21:06:36 UTC (rev 244) @@ -1,105 +0,0 @@ -#ifndef DHCPDEMON_H -#define DHCPDEMON_H - -#include "ipaddress.h" -#include "macaddress.h" - -class UdpSocket; -class DhcpPacket; -class Interface; -class StaticDhcpRecord; -class DhcpServerModel; - -struct ClientState { - int xid; - int state; - MacAddress mac; - IpAddress ip; - IpAddress mask; - IpAddress gateway; - int time; - int requestTimer; - enum { WAIT_REQUEST = 0, IN_USE = 1, DECLINE = 2 }; - ClientState(StaticDhcpRecord *rec) { - - } - - ClientState() { } -}; - -class DhcpDemon : public QObject -{ - Q_OBJECT - Q_PROPERTY( QString interfaceName READ interfaceName WRITE setInterfaceName ) - Q_PROPERTY( QString beginIp READ beginIp WRITE setBeginIp ) - Q_PROPERTY( QString endIp READ endIp WRITE setEndIp ) - Q_PROPERTY( QString mask READ mask WRITE setMask ) - Q_PROPERTY( QString gateway READ gateway WRITE setGateway ) - Q_PROPERTY( int time READ time WRITE setTime ) - Q_PROPERTY( int waitingTime READ waitingTime WRITE setWaitingTime ) - Q_PROPERTY( bool dynamic READ dynamic WRITE setDynamic ) -public: - enum { CLIENT_SOCKET = 67 , SERVER_SOCKET = 68 }; - - DhcpDemon(QObject* parent = 0); - DhcpDemon(Interface *inter); - ~DhcpDemon(); - void setInterfaceName( QString inter ) { myInterface = inter; } - void setBeginIp(QString ip) { myBeginIp.setIp(ip); } - void setEndIp(QString ip) { myEndIp.setIp(ip); } - void setMask(QString m) { myMask.setIp(m); } - void setGateway(QString g) { myGateway.setIp(g); } - void setTime(int t) { myTime = t; } - void setWaitingTime(int t) { myWaitingTime = t; } - void setDynamic(bool b) { myDynamic = b; } - QString interfaceName() const { return myInterface; } - QString beginIp() const { return myBeginIp.toString(); } - QString endIp() const { return myEndIp.toString(); } - QString mask() const { return myMask.toString(); } - QString gateway() const { return myGateway.toString(); } - int time() const { return myTime; } - int waitingTime() const { return myWaitingTime; } - bool dynamic() const { return myDynamic; } - DhcpServerModel* dhcpModel() { return myDhcpModel; } - void incTime(); - IpAddress giveDynamicIp() const; - - void read(QDataStream &stream); - -// Обработка пакетов -public: - void executeDiscover(DhcpPacket packet); - void executeRequest(DhcpPacket packet); - void executeDecline(DhcpPacket packet); - -// Функция инициализации для конструкторов -private: - void initialize(); - -// Функции создания и отправки ответа -private: - void makeAnswer(ClientState* client, int type); - void sendDhcp(DhcpPacket packet) const; - DhcpPacket createDhcpPacket(ClientState *client, int state) const; - -// Функции выбора и нахождения записи клиента -private: - ClientState* chooseStatic(DhcpPacket packet); - ClientState* chooseDynamic(DhcpPacket packet); - ClientState* findClient( int xid ) const; - ClientState* findClient(IpAddress ip) const; - -private: - QList<ClientState*> clients; - QString myInterface; - DhcpServerModel *myDhcpModel; - IpAddress myBeginIp; - IpAddress myEndIp; - IpAddress myMask; - IpAddress myGateway; - int myTime; - int myWaitingTime; - bool myDynamic; -}; - -#endif // DHCPDEMON_H Modified: trunk/src/programs/dhcpserverprogram.cpp =================================================================== --- trunk/src/programs/dhcpserverprogram.cpp 2011-02-11 23:05:12 UTC (rev 243) +++ trunk/src/programs/dhcpserverprogram.cpp 2011-02-12 21:06:36 UTC (rev 244) @@ -34,83 +34,77 @@ myName = tr("DHCP server"); myServerCount++; myServerName = QString("Server%1").arg(myServerCount); - myDemons.clear(); - qDeleteAll(myDemons); + myDaemons.clear(); + qDeleteAll(myDaemons); } DhcpServerProgram::~DhcpServerProgram() { - myDevice->disposeSocket(receiver); - myDemons.clear(); - qDeleteAll(myDemons); + myDaemons.clear(); + qDeleteAll(myDaemons); } void DhcpServerProgram::setDevice(SmartDevice *s) { if ( s == 0 ) return; Program::setDevice(s); - receiver = myDevice->openSocket(DhcpDemon::SERVER_SOCKET, SocketFactory::UDP); - //receiver = new udpSocket(myDevice, SERVER_SOCKET); foreach ( Interface *i, myDevice->interfaces() ) { if ( i->isConnect() ) { - DhcpDemon *demon = new DhcpDemon(i); - myDemons << demon; + DhcpDaemon *daemon = new DhcpDaemon(i, this); + myDaemons.insert(i, daemon); } } - receiver->setBind("0.0.0.0"); - connect( receiver , SIGNAL(readyRead(QByteArray)), SLOT(execute(QByteArray))); - connect( myDevice, SIGNAL(interfaceConnected(QString)), SLOT(checkInterface(QString)) ); + connect( myDevice, SIGNAL(interfaceConnected(QString)), SLOT(checkInterfaceOnConnect(QString)) ); + connect( myDevice, SIGNAL(interfaceDeleted(QString)), SLOT(checkInterfaceOnDelete(QString)) ); } -//void dhcpServerProgramm::checkInterface(QString port) -//{ -// if ( myInterface.isEmpty() ) setInterfaceName(port); -//} - -void DhcpServerProgram::execute(QByteArray data) +void DhcpServerProgram::checkInterfaceOnConnect(QString port) { - DhcpPacket packet(data); - foreach ( DhcpDemon *demon, myDemons ) { - IpAddress deviceIp = myDevice->adapter(demon->interfaceName())->ip(); - if ( deviceIp.isEmpty() ) { - QMessageBox::warning(0,tr("Warning"), - tr("Your DHCP server <i>%1</i> isn't configured.").arg(myServerName), - QMessageBox::Ok, QMessageBox::Ok); - return; - } + Interface *i = myDevice->adapter(port); + if ( !myDaemons.contains(i) ) { + DhcpDaemon *daem = new DhcpDaemon(i, this); + myDaemons.insert(i, daem); + } +} - if ( deviceIp == packet.siaddr() ) { - switch ( packet.type() ) { - case DhcpPacket::DHCPDISCOVER : - demon->executeDiscover(packet); - break; - case DhcpPacket::DHCPREQUEST : - demon->executeRequest(packet); - break; - case DhcpPacket::DHCPDECLINE : - demon->executeDecline(packet); - break; - } - } +void DhcpServerProgram::checkInterfaceOnDelete(QString port) +{ + Interface *i = myDevice->adapter(port); + if ( !myDaemons.contains(i) ) { + DhcpDaemon *daem = myDaemons.take(i); + delete daem; } } - - void DhcpServerProgram::incTime() { - foreach ( DhcpDemon *demon, myDemons ) { + foreach ( DhcpDaemon *demon, myDaemons.values() ) { demon->incTime(); } } void DhcpServerProgram::showProperty() { - DhcpServerProperty *d = new DhcpServerProperty(myDevice); - d->setProgramm(this); + DhcpServerSetting *setting = new DhcpServerSetting(this); + DhcpServerProperty *d = new DhcpServerProperty(setting); d->exec(); } +DhcpDaemon* DhcpServerProgram::daemonOf(Interface *inter) +{ + return myDaemons.value(inter); +} + +void DhcpServerProgram::addDhcpDaemon(DhcpDaemon *daemon) +{ + Interface *i = daemon->interface(); + if ( !i ) { + i = myDevice->adapter(daemon->interfaceName()); + daemon->setInterface(i); + } + myDaemons.insert(i, daemon); +} + /*! Записывает отличительные черты в поток. @param stream - поток для записи. @@ -119,7 +113,7 @@ { stream << DHCPServer; Program::write(stream); - DhcpDemon *d = myDemons.at(0); + DhcpDaemon *d = myDaemons.values().at(0); d->dhcpModel()->write(stream); stream << d->interfaceName(); stream << d->beginIp(); @@ -139,21 +133,9 @@ void DhcpServerProgram::read(QDataStream &stream) { Program::read(stream); - DhcpDemon *d = new DhcpDemon(device()->interfaces().at(0)); + DhcpDaemon *d = new DhcpDaemon(device()->interfaces().at(0)); d->dhcpModel()->read(stream); d->read(stream); } //--------------------------------------------------- - - -//--------------------------------------------------- -//СlientState::СlientState(StaticDhcpRecord *rec) -//{ -// ip = rec->yiaddr; -// mac = rec->chaddr; -// mask = rec->mask; -// gateway = rec->gateway; -// time = rec->time; -//} - Modified: trunk/src/programs/dhcpserverprogram.h =================================================================== --- trunk/src/programs/dhcpserverprogram.h 2011-02-11 23:05:12 UTC (rev 243) +++ trunk/src/programs/dhcpserverprogram.h 2011-02-12 21:06:36 UTC (rev 244) @@ -21,7 +21,7 @@ #define DHCPSERVERPROGRAMM_H #include "program.h" -#include "dhcpdemon.h" +#include "dhcpdaemon.h" class AbstractSocket; @@ -47,17 +47,31 @@ void write(QDataStream &stream) const; void read(QDataStream &stream); -// Слоты + DhcpDaemon* daemonOf(Interface *inter); + + Q_INVOKABLE void addDhcpDaemon(DhcpDaemon *daemon); + + // Слоты public slots: - void execute(QByteArray data); -// void checkInterface(QString port); + void checkInterfaceOnConnect(QString port); + void checkInterfaceOnDelete(QString port); // Переменные private: static int myServerCount; QString myServerName; - QList<DhcpDemon*> myDemons; - AbstractSocket *receiver; + QMap<Interface*, DhcpDaemon*> myDaemons; }; +class DhcpServerSetting +{ +public: + DhcpServerSetting(DhcpServerProgram *prog) { myProgram = prog; } + DhcpServerProgram* program() { return myProgram; } + DhcpDaemon* daemonOf(Interface *inter) { return myProgram->daemonOf(inter); } + +private: + DhcpServerProgram *myProgram; +}; + #endif // DHCPSERVERPROGRAMM_H Modified: trunk/src/programs/programs.pri =================================================================== --- trunk/src/programs/programs.pri 2011-02-11 23:05:12 UTC (rev 243) +++ trunk/src/programs/programs.pri 2011-02-12 21:06:36 UTC (rev 244) @@ -3,10 +3,10 @@ src/programs/dhcpserverprogram.h \ src/programs/dhcpclientprogram.h \ src/programs/spoofingprogram.h \ - src/programs/dhcpdemon.h + src/programs/dhcpdaemon.h SOURCES += src/programs/ripprogram.cpp \ src/programs/program.cpp \ src/programs/dhcpserverprogram.cpp \ src/programs/dhcpclientprogram.cpp \ src/programs/spoofingprogram.cpp \ - src/programs/dhcpdemon.cpp + src/programs/dhcpdaemon.cpp This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |