/* * NATItem.cpp * * Created on: 11-01-2017 * Author: Piotr Dergun */ #include "NATRouter.h" void NATRouter::initalizeNatTable() { try { natTable = new NATItem[65536]; } catch (bad_alloc &ba) { cerr << "Nie mozna zaalokowac pamieci dla tablicy NAT!" << endl; exit(1); } } 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=1; i<65536; ++i) if (this->natTable[i].isFree()) return i; return -1; // nie ma żadnego wolnego portu } NATRouter::~NATRouter() { if (natTable) delete [] natTable; } void NATRouter::onRecv() { while (true) { Packet p = this->recv(); if (p.getSrcPort() != 0) { // 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() && p.getDstIp() != this->getIp()) { this->send(p, true); } else if (p.getDstIp() != this->getIp() && p.getDstIp() != this->getWanIp()) { this->sNAT(&p); } else if (p.getDstIp() == this->getWanIp() && !this->natTable[p.getDstPort()].isFree()) { this->dNAT(&p); } else { // TUTAJ ew. implementacja obslugi pakietu adresowanego do routera } } else { this->print("onRecv() sleeping..."); sleep(1); } } } void NATRouter::setWanIp(string wanIp) { this->netWanConf.ip = wanIp; this->setWanNetwork(); } void NATRouter::setWanMask(string wanMask) { this->netWanConf.mask = wanMask; this->setWanNetwork(); } void NATRouter::setWanGatewayIp(string wanGatewayIp) { this->netWanConf.gatewayIp = wanGatewayIp; } string NATRouter::getWanIp() { return this->netWanConf.ip; } string NATRouter::getWanMask() { return this->netWanConf.mask; } /* * funkcja SNAT zapisuje w tablicy NAT * numer portu zrodlowego komputera z LAN * oraz jego IP i przeksztalca pakiet, zmieniajac * zrodlowy IP na IP zewn. routera oraz wolny * port z tablicy NAT. Jezeli portu nie ma to funkcja * czeka, az sie zwolni */ void NATRouter::sNAT(Packet *packet) { int port; NATItem *natItem; // mozliwe, ze juz port zostal zaalokowany, to trzeba wykorzystac port = this->getAllocatedPort(packet->getSrcIp(), packet->getSrcPort()); if (port == -1) while ((port = this->getFreePort()) == -1) { //TESTOWO //cout << "Brak wolnych portow, czekam 1s" << endl; sleep(1); } // wstawiam do tablicy NAT info ze port zarezerowany na odbior 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 this->send(*packet, true); // wysylam dalej natItem = NULL; } /* * funkcja DNAT ma za zadanie znalezc w tablicy NAT * port i adres IP wezla na ktory ma wrocic odpowiedz * z sieci Internet (z zewnatrz), a takze przedluzyc * czas zycia tego portu */ void NATRouter::dNAT(Packet* packet) { NATItem *natItem = &this->natTable[packet->getDstPort()]; packet->setDstIp(natItem->getIp()); // zamieniam IP lokalne na WAN'owe packet->setDstPort(natItem->getPort()); // zamieniam port NAT na lokalny wezla //natItem->free(); // zwalniam port w routerze natItem->increaseTimeout(5); // podbijam o kolejne 5 sekund skoro transmisja trwa this->send(*packet, true); // wysylam dalej natItem = NULL; } void NATRouter::setWanNetwork() { this->netWanConf.network = this->calculateNetwork(this->getWanIp(), this->getWanMask()); } string NATRouter::getWanNetwork() { return this->netWanConf.network; } /* * funkcja szuka aktywnego zaalokowanego portu (aktywna * transmisja) w tablicy NAT dla pary (srcIp:srcPort) */ int NATRouter::getAllocatedPort(string srcIp, int srcPort) { for (int i=1; i<65536; ++i) if (this->natTable[i].getIp() == srcIp && this->natTable[i].getPort() == srcPort) return i; return -1; // nic nie znaleziono } string NATRouter::getWanGatewayIp() { return this->netWanConf.gatewayIp; }