/*
							 | 
						|
								 * NATItem.cpp
							 | 
						|
								 *
							 | 
						|
								 *  Created on: 10-01-2017
							 | 
						|
								 *      Author: Piotr Dergun
							 | 
						|
								 */
							 | 
						|
								
							 | 
						|
								#include "NATRouter.h"
							 | 
						|
								
							 | 
						|
								void NATRouter::initalizeNatTable()
							 | 
						|
								{
							 | 
						|
									try
							 | 
						|
									{
							 | 
						|
										natTable = new NATItem[65536];
							 | 
						|
									}
							 | 
						|
									catch (bad_alloc &ba)
							 | 
						|
									{
							 | 
						|
										cerr << "Nie mozna zaalokowac pamieci dla tablicy NAT!" << endl;
							 | 
						|
										exit(1);
							 | 
						|
									}
							 | 
						|
								}
							 | 
						|
								
							 | 
						|
								NATRouter::NATRouter()
							 | 
						|
								{
							 | 
						|
									this->initalizeNatTable();
							 | 
						|
								}
							 | 
						|
								
							 | 
						|
								NATRouter::NATRouter(string hostname) : Node(hostname)
							 | 
						|
								{
							 | 
						|
									this->initalizeNatTable();
							 | 
						|
								}
							 | 
						|
								
							 | 
						|
								NATRouter::NATRouter(string hostname, string ip, string mask) : Node(hostname, ip, mask)
							 | 
						|
								{
							 | 
						|
									this->initalizeNatTable();
							 | 
						|
								}
							 | 
						|
								
							 | 
						|
								NATRouter::NATRouter(string hostname, string ip, string mask, string gatewayIp) : Node(hostname, ip, mask, gatewayIp)
							 | 
						|
								{
							 | 
						|
									this->initalizeNatTable();
							 | 
						|
								}
							 | 
						|
								
							 | 
						|
								int NATRouter::getFreePort()
							 | 
						|
								{
							 | 
						|
									for (int i=1; i<65536; ++i)
							 | 
						|
										if (this->natTable[i].isFree())
							 | 
						|
											return i;
							 | 
						|
								
							 | 
						|
									return -1;	// nie ma żadnego wolnego portu
							 | 
						|
								}
							 | 
						|
								
							 | 
						|
								NATRouter::~NATRouter()
							 | 
						|
								{
							 | 
						|
									if (natTable)
							 | 
						|
										delete [] natTable;
							 | 
						|
								}
							 | 
						|
								
							 | 
						|
								void NATRouter::onRecv()
							 | 
						|
								{
							 | 
						|
									Packet p = this->recv();
							 | 
						|
								
							 | 
						|
									// TODO: jako ze router jest tez switchem, zaimplementowac wysylanie wiadomosci po sieci lokalnej
							 | 
						|
									if (p.getSrcPort() != 0)
							 | 
						|
									{
							 | 
						|
										// jezeli pakiet idzie z jednego wezla do drugiego w danej possieci to odeslij mu "jak switch"
							 | 
						|
										if (this->calculateNetwork(p.getDstIp(), this->getMask()) == this->getNetwork())
							 | 
						|
										{
							 | 
						|
											this->send(p, true);
							 | 
						|
										}
							 | 
						|
										else if (p.getDstIp() != this->getIp() && p.getDstIp() != this->getWanIp())
							 | 
						|
										{
							 | 
						|
											this->sNAT(&p);
							 | 
						|
										}
							 | 
						|
										else if (p.getDstIp() == this->getWanIp() && !this->natTable[p.getDstPort()].isFree())
							 | 
						|
										{
							 | 
						|
											this->dNAT(&p);
							 | 
						|
										}
							 | 
						|
										else
							 | 
						|
										{
							 | 
						|
											// TUTAJ ew. implementacja obslugi pakietu adresowanego do routera
							 | 
						|
										}
							 | 
						|
									}
							 | 
						|
								}
							 | 
						|
								
							 | 
						|
								void NATRouter::setWanIp(string wanIp)
							 | 
						|
								{
							 | 
						|
									this->netWanConf.ip = wanIp;
							 | 
						|
								}
							 | 
						|
								
							 | 
						|
								void NATRouter::setWanMask(string wanMask)
							 | 
						|
								{
							 | 
						|
									this->netWanConf.mask = wanMask;
							 | 
						|
								}
							 | 
						|
								
							 | 
						|
								void NATRouter::setWanGatewayIp(string wanGatewayIp)
							 | 
						|
								{
							 | 
						|
									this->netWanConf.gatewayIp = wanGatewayIp;
							 | 
						|
								}
							 | 
						|
								
							 | 
						|
								string NATRouter::getWanIp()
							 | 
						|
								{
							 | 
						|
									return this->netWanConf.ip;
							 | 
						|
								}
							 | 
						|
								
							 | 
						|
								string NATRouter::getWanMask()
							 | 
						|
								{
							 | 
						|
									return this->netWanConf.mask;
							 | 
						|
								}
							 | 
						|
								
							 | 
						|
								void NATRouter::sNAT(Packet *packet)
							 | 
						|
								{
							 | 
						|
									int port;
							 | 
						|
									NATItem *natItem;
							 | 
						|
								
							 | 
						|
									while ((port = this->getFreePort()) == -1)
							 | 
						|
									{
							 | 
						|
										//TESTOWO
							 | 
						|
										cout << "Brak wolnych portow, czekam 1s" << endl;
							 | 
						|
										sleep(1);
							 | 
						|
									}
							 | 
						|
								
							 | 
						|
									// wstawiam do tablicy NAT info ze port zarezerowany na odbior
							 | 
						|
									natItem = &this->natTable[port];
							 | 
						|
									natItem->setIp(packet->getSrcIp());
							 | 
						|
									natItem->setPort(packet->getSrcPort());
							 | 
						|
									natItem->setTimeout(5);
							 | 
						|
								
							 | 
						|
									packet->setSrcIp(this->getWanIp());	// zamieniam IP lokalne na WAN'owe
							 | 
						|
									packet->setSrcPort(port);			// zamieniam port lokalny na WAN'owy - z tablicy NAT
							 | 
						|
								
							 | 
						|
									this->send(*packet, true);			// wysylam dalej
							 | 
						|
								
							 | 
						|
									natItem = NULL;
							 | 
						|
								}
							 | 
						|
								
							 | 
						|
								void NATRouter::dNAT(Packet* packet)
							 | 
						|
								{
							 | 
						|
									NATItem *natItem = &this->natTable[packet->getDstPort()];
							 | 
						|
								
							 | 
						|
									packet->setDstIp(natItem->getIp());		// zamieniam IP lokalne na WAN'owe
							 | 
						|
									packet->setDstPort(natItem->getPort());	// zamieniam port NAT na lokalny wezla
							 | 
						|
									natItem->free();						// zwalniam port w routerze
							 | 
						|
								
							 | 
						|
									this->send(*packet, true);				// wysylam dalej
							 | 
						|
								
							 | 
						|
									natItem = NULL;
							 | 
						|
								}
							 | 
						|
								
							 | 
						|
								string NATRouter::getWanGatewayIp()
							 | 
						|
								{
							 | 
						|
									return this->netWanConf.gatewayIp;
							 | 
						|
								}
							 |