zaimplementowanie funkcjonalnosci sieci lokalnej: NATRouter moze miec polaczenia do komputerow (a'la switch) i przekazywac pakiety
implementacja liczenia adresu podsieci
This commit is contained in:
57
Main.cpp
57
Main.cpp
@@ -7,32 +7,81 @@
|
||||
|
||||
#include "common.h"
|
||||
#include "Node.h"
|
||||
#include "NATRouter.h"
|
||||
|
||||
int main(int argc, char *argv[])
|
||||
{
|
||||
cout << "Obiekt PC1" << endl;
|
||||
Node pc1("PC1", "10.0.0.2", "255.0.0.0");
|
||||
Node pc1("PC1", "10.0.0.2", "255.0.0.0", "10.0.0.1");
|
||||
|
||||
cout << "Obiekt PC2" << endl;
|
||||
Node pc2("PC2", "10.0.0.3", "255.0.0.0");
|
||||
Node pc2("PC2", "10.0.0.3", "255.0.0.0", "10.0.0.1");
|
||||
|
||||
cout << "Obiekt R1" << endl;
|
||||
NATRouter r1("R1", "10.0.0.1", "255.255.255.0");
|
||||
r1.setWanIp("83.11.254.254");
|
||||
r1.setWanMask("255.255.255.255");
|
||||
|
||||
cout << "Podlaczam PC1, PC2 z R1" << endl;
|
||||
cout << r1.connectNode(&pc1) << endl;
|
||||
cout << r1.connectNode(&pc2) << endl;
|
||||
|
||||
cout << "Obiekt S" << endl;
|
||||
Node s("Serwer", "8.8.8.8", "255.255.255.255");
|
||||
s.connectNode(&r1);
|
||||
|
||||
/*
|
||||
* zastapilem to polaczenie bezposrednie
|
||||
* polaczeniem przez router (a'la switch)
|
||||
|
||||
cout << "Lacze PC1 z PC2" << endl;
|
||||
cout << pc1.connectNode(&pc2) << endl;
|
||||
|
||||
cout << "Lacze PC1 z PC2 (ponownie)" << endl;
|
||||
cout << pc1.connectNode(&pc2) << endl;
|
||||
|
||||
*/
|
||||
cout << "Tworze pakiet i adresuje go do PC2" << endl;
|
||||
Packet p("piekna wiadomosc");
|
||||
|
||||
p.setDstIp("10.0.0.3");
|
||||
p.setDstPort(80);
|
||||
|
||||
cout << "Wysylam wiadomosc: ";
|
||||
cout << "Wysylam wiadomosc z PC1: ";
|
||||
cout << pc1.send(p) << endl;
|
||||
|
||||
cout << "Wywoluje onRecv() na R1 <-- pelni funkcje switcha" << endl;
|
||||
r1.onRecv();
|
||||
|
||||
cout << "Wywoluje onRecv() na PC2" << endl;
|
||||
pc2.onRecv();
|
||||
|
||||
cout << "Adresuje pakiet do serwera" << endl;
|
||||
p.setDstIp("8.8.8.8");
|
||||
p.setDstPort(80);
|
||||
p.setMsg("to wiadomosc do serwera!");
|
||||
|
||||
cout << "Wysylam wiadomosc z PC1: ";
|
||||
cout << pc1.send(p) << endl;
|
||||
|
||||
cout << "Wywoluje onRecv() na R1 <-- pelni funkcje SNAT" << endl;
|
||||
r1.onRecv();
|
||||
|
||||
cout << "Wywoluje onRecv() na serwerze" << endl;
|
||||
s.onRecv();
|
||||
|
||||
cout << "Serwer generuje odpowiedz (tymczasowo, poki nie ma swojej klasy)" << endl;
|
||||
Packet rp("Odpowiedz z serwera do PC1");
|
||||
rp.setDstIp("83.11.254.254");
|
||||
rp.setDstPort(1);
|
||||
|
||||
cout << "Wysylam wiadomosc z serwera: ";
|
||||
cout << s.send(rp) << endl;
|
||||
|
||||
cout << "Wywoluje onRecv() na R1 <-- pelni funkcje DNAT" << endl;
|
||||
r1.onRecv();
|
||||
|
||||
cout << "Wywoluje onRecv() na PC1" << endl;
|
||||
pc1.onRecv();
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -7,7 +7,7 @@
|
||||
|
||||
#include "NATRouter.h"
|
||||
|
||||
NATRouter::NATRouter()
|
||||
void NATRouter::initalizeNatTable()
|
||||
{
|
||||
try
|
||||
{
|
||||
@@ -20,9 +20,29 @@ NATRouter::NATRouter()
|
||||
}
|
||||
}
|
||||
|
||||
NATRouter::NATRouter()
|
||||
{
|
||||
this->initalizeNatTable();
|
||||
}
|
||||
|
||||
NATRouter::NATRouter(string hostname) : Node(hostname)
|
||||
{
|
||||
this->initalizeNatTable();
|
||||
}
|
||||
|
||||
NATRouter::NATRouter(string hostname, string ip, string mask) : Node(hostname, ip, mask)
|
||||
{
|
||||
this->initalizeNatTable();
|
||||
}
|
||||
|
||||
NATRouter::NATRouter(string hostname, string ip, string mask, string gatewayIp) : Node(hostname, ip, mask, gatewayIp)
|
||||
{
|
||||
this->initalizeNatTable();
|
||||
}
|
||||
|
||||
int NATRouter::getFreePort()
|
||||
{
|
||||
for (int i=0; i<65536; ++i)
|
||||
for (int i=1; i<65536; ++i)
|
||||
if (this->natTable[i].isFree())
|
||||
return i;
|
||||
|
||||
@@ -39,9 +59,15 @@ void NATRouter::onRecv()
|
||||
{
|
||||
Packet p = this->recv();
|
||||
|
||||
// TODO: jako ze router jest tez switchem, zaimplementowac wysylanie wiadomosci po sieci lokalnej
|
||||
if (p.getSrcPort() != 0)
|
||||
{
|
||||
if (p.getDstIp() != this->getIp() && p.getDstIp() != this->getWanIp())
|
||||
// jezeli pakiet idzie z jednego wezla do drugiego w danej possieci to odeslij mu "jak switch"
|
||||
if (this->calculateNetwork(p.getDstIp(), this->getMask()) == this->getNetwork())
|
||||
{
|
||||
this->send(p, true);
|
||||
}
|
||||
else if (p.getDstIp() != this->getIp() && p.getDstIp() != this->getWanIp())
|
||||
{
|
||||
this->sNAT(&p);
|
||||
}
|
||||
@@ -97,6 +123,8 @@ void NATRouter::sNAT(Packet *packet)
|
||||
natItem = &this->natTable[port];
|
||||
natItem->setIp(packet->getSrcIp());
|
||||
natItem->setPort(packet->getSrcPort());
|
||||
natItem->setTimeout(5);
|
||||
|
||||
packet->setSrcIp(this->getWanIp()); // zamieniam IP lokalne na WAN'owe
|
||||
packet->setSrcPort(port); // zamieniam port lokalny na WAN'owy - z tablicy NAT
|
||||
|
||||
|
||||
@@ -14,14 +14,18 @@
|
||||
|
||||
class NATRouter : public Node
|
||||
{
|
||||
NATItem *natTable; // tablica z zaalokowanymi portami na zewnątrz
|
||||
NATItem *natTable = NULL; // tablica z zaalokowanymi portami na zewnątrz
|
||||
NetConf netWanConf; // konfiguracja sieciowa na zewnątrz
|
||||
void initalizeNatTable();
|
||||
int getFreePort();
|
||||
void sNAT(Packet *packet);
|
||||
void dNAT(Packet *packet);
|
||||
|
||||
public:
|
||||
NATRouter();
|
||||
NATRouter(string hostname);
|
||||
NATRouter(string hostname, string ip, string mask);
|
||||
NATRouter(string hostname, string ip, string mask, string gatewayIp);
|
||||
~NATRouter();
|
||||
virtual void onRecv();
|
||||
|
||||
|
||||
58
Node.cpp
58
Node.cpp
@@ -6,9 +6,11 @@
|
||||
*/
|
||||
|
||||
#include "Node.h"
|
||||
#include "NATRouter.h"
|
||||
|
||||
Node * Node::findConnection(string ip)
|
||||
{
|
||||
NATRouter *ptr;
|
||||
if (ip == "0.0.0.0")
|
||||
return NULL;
|
||||
|
||||
@@ -17,6 +19,17 @@ Node * Node::findConnection(string ip)
|
||||
{
|
||||
if ((*it)->getIp() == ip)
|
||||
return *it;
|
||||
|
||||
/*
|
||||
* jezeli wezel ma polaczenie do NAT-routera
|
||||
* (i istnieje jego interfejs WAN to sprawdz
|
||||
* czy nie ma z nim bezposredniego polaczenia)
|
||||
*/
|
||||
ptr = dynamic_cast<NATRouter*>(*it);
|
||||
|
||||
if (ptr != NULL)
|
||||
if (ptr->getWanIp() == ip)
|
||||
return *it;
|
||||
}
|
||||
|
||||
return NULL;
|
||||
@@ -35,6 +48,32 @@ Packet Node::recv()
|
||||
return packet;
|
||||
}
|
||||
|
||||
string Node::ipToString(unsigned int ip)
|
||||
{
|
||||
ostringstream ss;
|
||||
ss << ((ip>>24)&0xFF) << "." << ((ip>>16)&0xFF) << "." << ((ip>>8)&0xFF) << "." << (ip&0xFF);
|
||||
|
||||
return ss.str();
|
||||
}
|
||||
|
||||
unsigned int Node::stringToIp(string ip)
|
||||
{
|
||||
istringstream iss(ip);
|
||||
int offset = 24;
|
||||
unsigned int res=0;
|
||||
|
||||
std::string token;
|
||||
while (getline(iss, token, '.')) {
|
||||
if (!token.empty())
|
||||
{
|
||||
res |= atoi(token.c_str()) << offset;
|
||||
offset -= 8;
|
||||
}
|
||||
}
|
||||
|
||||
return res;
|
||||
}
|
||||
|
||||
Node::Node()
|
||||
{
|
||||
this->setHostname("");
|
||||
@@ -143,15 +182,19 @@ void Node::setHostname(string hostname)
|
||||
void Node::setIp(string ip)
|
||||
{
|
||||
this->netConf.ip = ip;
|
||||
|
||||
this->setNetwork();
|
||||
}
|
||||
|
||||
void Node::setMask(string mask)
|
||||
{
|
||||
this->netConf.mask = mask;
|
||||
this->setNetwork();
|
||||
}
|
||||
|
||||
void Node::setGatewayIp(string gatewayIp)
|
||||
{
|
||||
// TODO mozna ewentualnie zrobic sprawdzenie czy gateway jest w podsieci
|
||||
this->netConf.gatewayIp = gatewayIp;
|
||||
}
|
||||
|
||||
@@ -175,6 +218,11 @@ string Node::getGatewayIp()
|
||||
return this->netConf.gatewayIp;
|
||||
}
|
||||
|
||||
string Node::calculateNetwork(string ip, string mask)
|
||||
{
|
||||
return ipToString(stringToIp(ip) & stringToIp(mask));
|
||||
}
|
||||
|
||||
void Node::onRecv()
|
||||
{
|
||||
// TESTOWO
|
||||
@@ -189,3 +237,13 @@ void Node::onRecv()
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
void Node::setNetwork()
|
||||
{
|
||||
this->netConf.network = this->calculateNetwork(this->netConf.ip, this->netConf.mask);
|
||||
}
|
||||
|
||||
string Node::getNetwork()
|
||||
{
|
||||
return this->netConf.network;
|
||||
}
|
||||
|
||||
12
Node.h
12
Node.h
@@ -10,22 +10,29 @@
|
||||
|
||||
#include "common.h"
|
||||
#include "Packet.h"
|
||||
|
||||
typedef struct {
|
||||
string ip;
|
||||
string mask;
|
||||
string network;
|
||||
string gatewayIp;
|
||||
} NetConf;
|
||||
|
||||
class Node
|
||||
{
|
||||
protected:
|
||||
private:
|
||||
queue<Packet>rcvBuffer; // kolejka z pakietami do przetworzenia
|
||||
vector<Node*> connectedNodes; // referencje do węzłów, z którymi jest podłączony
|
||||
NetConf netConf; // konfiguracja sieciowa
|
||||
string hostname; // nazwa węzła
|
||||
void setNetwork();
|
||||
protected:
|
||||
Node * findConnection(string ip);
|
||||
Packet recv();
|
||||
string ipToString(unsigned int ip);
|
||||
unsigned int stringToIp(string ip);
|
||||
public:
|
||||
string calculateNetwork(string ip, string mask);
|
||||
|
||||
public:
|
||||
Node();
|
||||
Node(string hostname);
|
||||
@@ -47,6 +54,7 @@ public:
|
||||
string getHostname();
|
||||
string getIp();
|
||||
string getMask();
|
||||
string getNetwork();
|
||||
string getGatewayIp();
|
||||
|
||||
virtual void onRecv(); // wirtualna metoda na odbiór i dalszą akcję
|
||||
|
||||
Reference in New Issue
Block a user