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.

259 lines
4.8 KiB

7 years ago
  1. /**
  2. * @file Node.cpp
  3. *
  4. * Created on: 10.01.2017
  5. * @author Piotr Dergun
  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. Packet Node::recv()
  44. {
  45. Packet packet;
  46. if (!this->rcvBuffer.empty())
  47. {
  48. packet = this->rcvBuffer.front();
  49. this->rcvBuffer.pop();
  50. }
  51. return packet;
  52. }
  53. string Node::ipToString(unsigned int ip)
  54. {
  55. ostringstream ss;
  56. ss << ((ip>>24)&0xFF) << "." << ((ip>>16)&0xFF) << "." << ((ip>>8)&0xFF) << "." << (ip&0xFF);
  57. return ss.str();
  58. }
  59. unsigned int Node::stringToIp(string ip)
  60. {
  61. istringstream iss(ip);
  62. int offset = 24;
  63. unsigned int res=0;
  64. std::string token;
  65. while (getline(iss, token, '.')) {
  66. if (!token.empty())
  67. {
  68. res |= atoi(token.c_str()) << offset;
  69. offset -= 8;
  70. }
  71. }
  72. return res;
  73. }
  74. Node::Node()
  75. {
  76. this->setHostname("");
  77. this->setIp("0.0.0.0");
  78. this->setMask("0.0.0.0");
  79. this->setGatewayIp("0.0.0.0");
  80. this->setObjectName(&this->hostname);
  81. this->setDelay(1);
  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. bool Node::connectNode(Node *node, bool isExternal, bool firstConnected)
  103. {
  104. if (node->getIp() == "0.0.0.0") // jezeli wezel nie ma skonfigurowanej sieci, nie mozna go przylaczyc
  105. return false;
  106. if (!firstConnected)
  107. {
  108. map<Node*, bool>::iterator it = this->connectedNodes.begin();
  109. for (; it != this->connectedNodes.end(); ++it) // sprawdzamy, czy połączenia już przypadkiem nie ma
  110. {
  111. if ((*it).first == node)
  112. return false;
  113. }
  114. }
  115. this->connectedNodes.insert(pair<Node*, bool>(node, isExternal)); // podłączamy drugi węzeł
  116. if (!firstConnected)
  117. node->connectNode(this, isExternal, true); // to samo w drugą stronę
  118. return true;
  119. }
  120. int Node::send(Packet packet, bool isRouter)
  121. {
  122. Node *node;
  123. node = this->findConnection(packet.getDstIp()); // znajdz bezposrednia trase
  124. if (!node)
  125. node = this->findConnection(this->getGatewayIp());
  126. if (!node)
  127. return false; // nie ma żadnej trasy do węzła
  128. if (packet.getDstPort() == 0)
  129. return false; // wypada zdefiniowac nadawce oraz docelowy port...
  130. // jezeli wezel nie jest routerem to ma ustawic pakietowi swoj srcIp oraz losowy port
  131. if (!isRouter)
  132. {
  133. packet.setSrcIp(this->getIp());
  134. if (packet.getSrcPort() == 0)
  135. {
  136. // ustaw port zrodlowy na port losowy z zakresu [32768,61000] - zob. empheral port (port emferyczny)
  137. packet.setSrcPort(rand() % 28233 + 32768);
  138. }
  139. }
  140. node->putPacket(packet);
  141. return packet.getSrcPort();
  142. }
  143. void Node::putPacket(Packet packet)
  144. {
  145. this->rcvBuffer.push(packet);
  146. }
  147. void Node::setHostname(string hostname)
  148. {
  149. this->hostname = hostname;
  150. }
  151. void Node::setIp(string ip)
  152. {
  153. this->netConf.ip = ip;
  154. this->setNetwork();
  155. }
  156. void Node::setMask(string mask)
  157. {
  158. this->netConf.mask = mask;
  159. this->setNetwork();
  160. }
  161. void Node::setGatewayIp(string gatewayIp)
  162. {
  163. // TODO mozna ewentualnie zrobic sprawdzenie czy gateway jest w podsieci
  164. this->netConf.gatewayIp = gatewayIp;
  165. }
  166. string Node::getHostname()
  167. {
  168. return this->hostname;
  169. }
  170. string Node::getIp()
  171. {
  172. return this->netConf.ip;
  173. }
  174. string Node::getMask()
  175. {
  176. return this->netConf.mask;
  177. }
  178. string Node::getGatewayIp()
  179. {
  180. return this->netConf.gatewayIp;
  181. }
  182. string Node::calculateNetwork(string ip, string mask)
  183. {
  184. return ipToString(stringToIp(ip) & stringToIp(mask));
  185. }
  186. void Node::onRecv()
  187. {
  188. while(true)
  189. {
  190. Packet p = this->recv();
  191. }
  192. }
  193. void Node::setNetwork()
  194. {
  195. this->netConf.network = this->calculateNetwork(this->getIp(), this->getMask());
  196. }
  197. string Node::getNetwork()
  198. {
  199. return this->netConf.network;
  200. }
  201. void Node::split(const string &s, char delim, vector<string> &elems)
  202. {
  203. stringstream ss;
  204. ss.str(s);
  205. string item;
  206. while (getline(ss, item, delim))
  207. {
  208. elems.push_back(item);
  209. }
  210. }
  211. vector<string> Node::split(const string &s, char delim)
  212. {
  213. vector<std::string> elems;
  214. split(s, delim, elems);
  215. return elems;
  216. }