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.

177 lines
3.6 KiB

  1. /*
  2. * NATItem.cpp
  3. *
  4. * Created on: 10-01-2017
  5. * Author: Piotr Dergun
  6. */
  7. #include "NATRouter.h"
  8. void NATRouter::initalizeNatTable()
  9. {
  10. try
  11. {
  12. natTable = new NATItem[65536];
  13. }
  14. catch (bad_alloc &ba)
  15. {
  16. cerr << "Nie mozna zaalokowac pamieci dla tablicy NAT!" << endl;
  17. exit(1);
  18. }
  19. }
  20. NATRouter::NATRouter()
  21. {
  22. this->initalizeNatTable();
  23. }
  24. NATRouter::NATRouter(string hostname) : Node(hostname)
  25. {
  26. this->initalizeNatTable();
  27. }
  28. NATRouter::NATRouter(string hostname, string ip, string mask) : Node(hostname, ip, mask)
  29. {
  30. this->initalizeNatTable();
  31. }
  32. NATRouter::NATRouter(string hostname, string ip, string mask, string gatewayIp) : Node(hostname, ip, mask, gatewayIp)
  33. {
  34. this->initalizeNatTable();
  35. }
  36. int NATRouter::getFreePort()
  37. {
  38. for (int i=1; i<65536; ++i)
  39. if (this->natTable[i].isFree())
  40. return i;
  41. return -1; // nie ma żadnego wolnego portu
  42. }
  43. NATRouter::~NATRouter()
  44. {
  45. if (natTable)
  46. delete [] natTable;
  47. }
  48. void NATRouter::onRecv()
  49. {
  50. Packet p = this->recv();
  51. if (p.getSrcPort() != 0)
  52. {
  53. // jezeli pakiet idzie z jednego wezla do drugiego w danej possieci to odeslij mu "jak switch"
  54. if (this->calculateNetwork(p.getDstIp(), this->getMask()) == this->getNetwork())
  55. {
  56. this->send(p, true);
  57. }
  58. else if (p.getDstIp() != this->getIp() && p.getDstIp() != this->getWanIp())
  59. {
  60. this->sNAT(&p);
  61. }
  62. else if (p.getDstIp() == this->getWanIp() && !this->natTable[p.getDstPort()].isFree())
  63. {
  64. this->dNAT(&p);
  65. }
  66. else
  67. {
  68. // TUTAJ ew. implementacja obslugi pakietu adresowanego do routera
  69. }
  70. }
  71. }
  72. void NATRouter::setWanIp(string wanIp)
  73. {
  74. this->netWanConf.ip = wanIp;
  75. this->setWanNetwork();
  76. }
  77. void NATRouter::setWanMask(string wanMask)
  78. {
  79. this->netWanConf.mask = wanMask;
  80. this->setWanNetwork();
  81. }
  82. void NATRouter::setWanGatewayIp(string wanGatewayIp)
  83. {
  84. this->netWanConf.gatewayIp = wanGatewayIp;
  85. }
  86. string NATRouter::getWanIp()
  87. {
  88. return this->netWanConf.ip;
  89. }
  90. string NATRouter::getWanMask()
  91. {
  92. return this->netWanConf.mask;
  93. }
  94. /*
  95. * funkcja SNAT zapisuje w tablicy NAT
  96. * numer portu zrodlowego komputera z LAN
  97. * oraz jego IP i przeksztalca pakiet, zmieniajac
  98. * zrodlowy IP na IP zewn. routera oraz wolny
  99. * port z tablicy NAT. Jezeli portu nie ma to funkcja
  100. * czeka, az sie zwolni
  101. */
  102. void NATRouter::sNAT(Packet *packet)
  103. {
  104. int port;
  105. NATItem *natItem;
  106. while ((port = this->getFreePort()) == -1)
  107. {
  108. //TESTOWO
  109. cout << "Brak wolnych portow, czekam 1s" << endl;
  110. sleep(1);
  111. }
  112. // wstawiam do tablicy NAT info ze port zarezerowany na odbior
  113. natItem = &this->natTable[port];
  114. natItem->setIp(packet->getSrcIp());
  115. natItem->setPort(packet->getSrcPort());
  116. natItem->setTimeout(5);
  117. packet->setSrcIp(this->getWanIp()); // zamieniam IP lokalne na WAN'owe
  118. packet->setSrcPort(port); // zamieniam port lokalny na WAN'owy - z tablicy NAT
  119. this->send(*packet, true); // wysylam dalej
  120. natItem = NULL;
  121. }
  122. /*
  123. * funkcja DNAT ma za zadanie znalezc w tablicy NAT
  124. * port i adres IP wezla na ktory ma wrocic odpowiedz
  125. * z sieci Internet (z zewnatrz), a takze zwolnic ten
  126. * port
  127. */
  128. void NATRouter::dNAT(Packet* packet)
  129. {
  130. NATItem *natItem = &this->natTable[packet->getDstPort()];
  131. packet->setDstIp(natItem->getIp()); // zamieniam IP lokalne na WAN'owe
  132. packet->setDstPort(natItem->getPort()); // zamieniam port NAT na lokalny wezla
  133. natItem->free(); // zwalniam port w routerze
  134. this->send(*packet, true); // wysylam dalej
  135. natItem = NULL;
  136. }
  137. void NATRouter::setWanNetwork()
  138. {
  139. this->netWanConf.network = this->calculateNetwork(this->getWanIp(), this->getWanMask());
  140. }
  141. string NATRouter::getWanNetwork()
  142. {
  143. return this->netWanConf.network;
  144. }
  145. string NATRouter::getWanGatewayIp()
  146. {
  147. return this->netWanConf.gatewayIp;
  148. }