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.

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