/** * @file Node.cpp * * Created on: 10.01.2017 * @author Piotr Dergun */ #include "Node.h" #include "NATRouter.h" Node * Node::findConnection(string ip) { NATRouter *r; Node *ptr = NULL; if (ip == "0.0.0.0") return NULL; // najpierw szukam tras lokalnych map::iterator it = this->connectedNodes.begin(); for (; it != this->connectedNodes.end(); ++it) { //if ((*it)->getIp() == ip) if ((*it).first->getIp() == ip) { ptr = (*it).first; if ((*it).second == false) return ptr; } /* * jezeli wezel ma polaczenie do NAT-routera * (i istnieje jego interfejs WAN to sprawdz * czy nie ma z nim bezposredniego polaczenia) */ r = dynamic_cast((*it).first); if (r != NULL) if (r->getWanIp() == ip) return (*it).first; } /* jezeli takich nie ma, a jest zewnetrzna * to musze wskazac do niej */ if (ptr) return ptr; return NULL; } Packet Node::recv() { Packet packet; if (!this->rcvBuffer.empty()) { packet = this->rcvBuffer.front(); this->rcvBuffer.pop(); } 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(""); this->setIp("0.0.0.0"); this->setMask("0.0.0.0"); this->setGatewayIp("0.0.0.0"); this->setObjectName(&this->hostname); this->setDelay(1); } Node::~Node() { this->connectedNodes.clear(); while(!this->rcvBuffer.empty()) this->rcvBuffer.pop(); } Node::Node(string hostname) : Node() { this->setHostname(hostname); } Node::Node(string hostname, string ip, string mask) : Node(hostname) { this->setIp(ip); this->setMask(mask); } Node::Node(string hostname, string ip, string mask, string gatewayIp) : Node(hostname, ip, mask) { this->setGatewayIp(gatewayIp); } bool Node::connectNode(Node *node, bool isExternal, bool firstConnected) { if (node->getIp() == "0.0.0.0") // jezeli wezel nie ma skonfigurowanej sieci, nie mozna go przylaczyc return false; if (!firstConnected) { map::iterator it = this->connectedNodes.begin(); for (; it != this->connectedNodes.end(); ++it) // sprawdzamy, czy połączenia już przypadkiem nie ma { if ((*it).first == node) return false; } } this->connectedNodes.insert(pair(node, isExternal)); // podłączamy drugi węzeł if (!firstConnected) node->connectNode(this, isExternal, true); // to samo w drugą stronę return true; } int Node::send(Packet packet, bool isRouter) { Node *node; node = this->findConnection(packet.getDstIp()); // znajdz bezposrednia trase if (!node) node = this->findConnection(this->getGatewayIp()); if (!node) return false; // nie ma żadnej trasy do węzła if (packet.getDstPort() == 0) return false; // wypada zdefiniowac nadawce oraz docelowy port... // jezeli wezel nie jest routerem to ma ustawic pakietowi swoj srcIp oraz losowy port if (!isRouter) { packet.setSrcIp(this->getIp()); if (packet.getSrcPort() == 0) { // ustaw port zrodlowy na port losowy z zakresu [32768,61000] - zob. empheral port (port emferyczny) packet.setSrcPort(rand() % 28233 + 32768); } } node->putPacket(packet); return packet.getSrcPort(); } void Node::putPacket(Packet packet) { this->rcvBuffer.push(packet); } void Node::setHostname(string hostname) { this->hostname = 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; } string Node::getHostname() { return this->hostname; } string Node::getIp() { return this->netConf.ip; } string Node::getMask() { return this->netConf.mask; } string Node::getGatewayIp() { return this->netConf.gatewayIp; } string Node::calculateNetwork(string ip, string mask) { return ipToString(stringToIp(ip) & stringToIp(mask)); } void Node::onRecv() { while(true) { Packet p = this->recv(); } } void Node::setNetwork() { this->netConf.network = this->calculateNetwork(this->getIp(), this->getMask()); } string Node::getNetwork() { return this->netConf.network; } void Node::split(const string &s, char delim, vector &elems) { stringstream ss; ss.str(s); string item; while (getline(ss, item, delim)) { elems.push_back(item); } } vector Node::split(const string &s, char delim) { vector elems; split(s, delim, elems); return elems; }