Symulacja NAT na przedmiot Symulacje Komputerowe
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

249 lines
5.3 KiB

  1. /*
  2. * Node.cpp
  3. *
  4. * Created on: 10.01.2017
  5. * Author: piotrek
  6. */
  7. #include "Node.h"
  8. #include "NATRouter.h"
  9. Node * Node::findConnection(string ip)
  10. {
  11. NATRouter *ptr;
  12. if (ip == "0.0.0.0")
  13. return NULL;
  14. vector<Node*>::iterator it = this->connectedNodes.begin();
  15. for (; it != this->connectedNodes.end(); ++it)
  16. {
  17. if ((*it)->getIp() == ip)
  18. return *it;
  19. /*
  20. * jezeli wezel ma polaczenie do NAT-routera
  21. * (i istnieje jego interfejs WAN to sprawdz
  22. * czy nie ma z nim bezposredniego polaczenia)
  23. */
  24. ptr = dynamic_cast<NATRouter*>(*it);
  25. if (ptr != NULL)
  26. if (ptr->getWanIp() == ip)
  27. return *it;
  28. }
  29. return NULL;
  30. }
  31. /* funkcja pobiera i usuwa pakiet z bufora "karty sieciowej" */
  32. Packet Node::recv()
  33. {
  34. Packet packet;
  35. if (!this->rcvBuffer.empty())
  36. {
  37. packet = this->rcvBuffer.front();
  38. this->rcvBuffer.pop();
  39. }
  40. return packet;
  41. }
  42. string Node::ipToString(unsigned int ip)
  43. {
  44. ostringstream ss;
  45. ss << ((ip>>24)&0xFF) << "." << ((ip>>16)&0xFF) << "." << ((ip>>8)&0xFF) << "." << (ip&0xFF);
  46. return ss.str();
  47. }
  48. unsigned int Node::stringToIp(string ip)
  49. {
  50. istringstream iss(ip);
  51. int offset = 24;
  52. unsigned int res=0;
  53. std::string token;
  54. while (getline(iss, token, '.')) {
  55. if (!token.empty())
  56. {
  57. res |= atoi(token.c_str()) << offset;
  58. offset -= 8;
  59. }
  60. }
  61. return res;
  62. }
  63. Node::Node()
  64. {
  65. this->setHostname("");
  66. this->setIp("0.0.0.0");
  67. this->setMask("0.0.0.0");
  68. this->setGatewayIp("0.0.0.0");
  69. }
  70. Node::~Node()
  71. {
  72. this->connectedNodes.clear();
  73. while(!this->rcvBuffer.empty())
  74. this->rcvBuffer.pop();
  75. }
  76. Node::Node(string hostname) : Node()
  77. {
  78. this->setHostname(hostname);
  79. }
  80. Node::Node(string hostname, string ip, string mask) : Node(hostname)
  81. {
  82. this->setIp(ip);
  83. this->setMask(mask);
  84. }
  85. Node::Node(string hostname, string ip, string mask, string gatewayIp) : Node(hostname, ip, mask)
  86. {
  87. this->setGatewayIp(gatewayIp);
  88. }
  89. /*
  90. * funkcja symuluje typową sytuację: mamy kartę sieciową, a funkcja connectNode jest podłączeniem wtyczki
  91. * z jednej strony
  92. * @param firstConnected - oznacza, czy pierwsza strona jest podlaczona (jezeli nie to sprawdzamy
  93. * czy polaczenie juz gdzies zostalo przypadkowo nawiazane, nawiazujemy polaczenie, a nastepnie
  94. * przekazujemy sterowanie drugiemu wezlowi zeby zrobil to samo)
  95. */
  96. bool Node::connectNode(Node *node, bool firstConnected)
  97. {
  98. if (node->getIp() == "0.0.0.0") // jezeli wezel nie ma skonfigurowanej sieci, nie mozna go przylaczyc
  99. return false;
  100. if (!firstConnected)
  101. {
  102. vector<Node*>::iterator it = this->connectedNodes.begin();
  103. for (; it != this->connectedNodes.end(); ++it) // sprawdzamy, czy połączenia już przypadkiem nie ma
  104. {
  105. if (*it == node)
  106. return false;
  107. }
  108. }
  109. this->connectedNodes.push_back(node); // podłączamy drugi węzeł
  110. if (!firstConnected)
  111. node->connectNode(this, true); // to samo w drugą stronę
  112. return true;
  113. }
  114. /*
  115. * funkcja wysyla, czyli przekazuje kopie pakietu kolejnemu wezlowi - docelowemu lub bramie domyslnej
  116. * o ile jest skonfigurowana i istnieje do niej sciezka
  117. * TODO zaimplementowac porownywanie z maska - jezeli dstIp z maska nie gra, wysylac na ruter
  118. */
  119. bool Node::send(Packet packet, bool isRouter)
  120. {
  121. Node *node;
  122. node = this->findConnection(packet.getDstIp()); // znajdz bezposrednia trase
  123. if (!node)
  124. node = this->findConnection(this->getGatewayIp());
  125. if (!node)
  126. return false; // nie ma zadnej trasy do wezla
  127. if (packet.getDstPort() == 0)
  128. return false; // wypada zdefiniowac nadawce oraz docelowy port...
  129. // jezeli wezel nie jest routerem to ma ustawic pakietowi swoj srcIp oraz losowy port
  130. if (!isRouter)
  131. {
  132. packet.setSrcIp(this->getIp());
  133. // ustaw port zrodlowy na port losowy z zakresu [32768,61000] - zob. empheral port (port emferyczny)
  134. srand(time(NULL));
  135. packet.setSrcPort(rand() % 32768 + 28233);
  136. }
  137. node->putPacket(packet);
  138. return true;
  139. }
  140. /*
  141. * funkcja jest modelem karty sieciowej - odbiera dane z sieci i umieszcza je
  142. * w swoim buforze (czy tam systemie)
  143. */
  144. void Node::putPacket(Packet packet)
  145. {
  146. this->rcvBuffer.push(packet);
  147. }
  148. void Node::setHostname(string hostname)
  149. {
  150. this->hostname = hostname;
  151. }
  152. void Node::setIp(string ip)
  153. {
  154. this->netConf.ip = ip;
  155. this->setNetwork();
  156. }
  157. void Node::setMask(string mask)
  158. {
  159. this->netConf.mask = mask;
  160. this->setNetwork();
  161. }
  162. void Node::setGatewayIp(string gatewayIp)
  163. {
  164. // TODO mozna ewentualnie zrobic sprawdzenie czy gateway jest w podsieci
  165. this->netConf.gatewayIp = gatewayIp;
  166. }
  167. string Node::getHostname()
  168. {
  169. return this->hostname;
  170. }
  171. string Node::getIp()
  172. {
  173. return this->netConf.ip;
  174. }
  175. string Node::getMask()
  176. {
  177. return this->netConf.mask;
  178. }
  179. string Node::getGatewayIp()
  180. {
  181. return this->netConf.gatewayIp;
  182. }
  183. string Node::calculateNetwork(string ip, string mask)
  184. {
  185. return ipToString(stringToIp(ip) & stringToIp(mask));
  186. }
  187. void Node::onRecv()
  188. {
  189. // TESTOWO
  190. Packet p = this->recv();
  191. if (p.getSrcPort() != 0)
  192. {
  193. cout << endl << "<<<<<< " << this->getHostname() << " >>>>>>" << endl;
  194. cout << "Odebrano wiadomosc!" << endl;
  195. cout << "Src: " << p.getSrcIp() << ":" << p.getSrcPort() << endl;
  196. cout << "Dst: " << p.getDstIp() << ":" << p.getDstPort() << endl;
  197. cout << "---" << endl << p.getMsg() << endl << endl;
  198. }
  199. }
  200. void Node::setNetwork()
  201. {
  202. this->netConf.network = this->calculateNetwork(this->netConf.ip, this->netConf.mask);
  203. }
  204. string Node::getNetwork()
  205. {
  206. return this->netConf.network;
  207. }