Escolar Documentos
Profissional Documentos
Cultura Documentos
1. Introduo
O Network Simulator 3 (ns-3) um simulador de rede que pretende ser uma nova alternativa ao popular Network Simulator 2 (ns-2). O ns-3 um software gratuito, distribudo sob a licena GNU GPLv2 e que disponibilizado gratuitamente para investigao, desenvolvimento e utilizao. O desenvolvimento do ns-3 comeou em Julho de 2006 e est programado que dure cerca de quatro anos. O projecto ns-3 financiado por vrias instituies como a Universidade de Washington, o Georgia Institute of Technology e o ICSI Center for Internet Research, tendo ainda o suporte do Plante research group do INRIA Sophia-Antipolis. O ns-3 escrito em C++ e Python e esta disponvel para vrios sistema operativos como Linux, OS X e Windows (atravs utilizao do Cygwin).
2. Objectivos
Nesta ficha pretende-se explicar o funcionamento geral do simulador ns-3 e o desenvolvimentos de alguns scripts C / Python que simulem topologias simples. Ao mesmo tempo sero mostrados alguns mtodos para avaliao dos resultados obtidos, atravs da utilizao do NAM The Network Animator para a visualizao grfica da simulao e tambm do Wireshark para uma anlise mais detalhada dos pacotes.
3. Instalao e documentao
As duas principais dependncias exigidas para a instalao de ns-3 so: uma instalao actualizada de Python (2.4 ou acima) e um compilador GNU C. Assim como a alternativa de simulao anterior (ns2), ns-3 distribudo de duas formas: em uma verso compacta (all-in-one) e tambm uma verso do cdigo fonte disponvel em repositrios remotos (neste caso Mercurial). Caso a escolha tenha sido pela distribuio compacta, importante observar os requisitos de software necessrios para a devida instalao de ns-3. Essa lista de pr-requisitos pode ser encontrada em: http://www.nsnam.org/wiki/index.php/Installation e dependem da distribuio linux em que ser feita a instalao.
IRC 2009/2010
Caso a escolha tenha sido a distribuio compacta, a instalao d-se pela execuo das seguintes instrues:
tar xvf ns-allinone-3.6.tar.bz2 cd ns-allinone-3.6 ./build.py
Posteriormente, torna-se necessrio configurar o ambiente ns. Embora a maioria das aplicaes linux se baseiem no uso de make para este propsito, o ns-3 baseia-se na aplicao waf que um sistema de build especfico para python. Desta forma, o prximo passo ser:
./waf configure
Um ltimo passo para avaliar se a instalao ocorreu correctamente o teste da instalao. Este teste pode ser feito pela execuo da seguinte instruo:
./test.py
Uma peculiaridade para esta verso do simulador ns-3 so os distintos formatos permitidos para o trace de pacotes e trfego das simulaes. Os ficheiros de trace gerados no ns-2 no so mais lidos nesta verso. Para este novo formato de ficheiros de trace, deve-se utilizar uma aplicao que capaz de analisar e animar as ligaes point-to-point peculiares ao ns-3. Esta aplicao a NetAnim (http://www.nsnam.org/wiki/index.php/NetAnim). Conforme ser observado nos exemplos posteriores, ns-3 trata a construo de ligaes entre ns de uma topologia atravs de ligaes conhecidas como point-to-point. Essas ligaes diferem-se do formato dos canais estabelecidos em ns2. Outra estratgia comum em ns-3 e analisar o trfego pela inspeo de pacotes. Essa uma tcnica bastante comum entre os analisadores de protocolos tais como o Wireshark (http://www.wireshark.org/) ou o tcpdump. Para este fim, conforme ser discutido no segundo script, podem ser gerados ficheiros com a extenso pcap que representam uma inspeo detalhada de pacotes em modo promscuo. Com o intuito de diminuir a complexidade do processo de instalao, configurao e teste, provemos para esta ficha uma mquina virtual gerada a partir do sistema operativo Linux Ubuntu 9.10. Nesta mquina virtual j esto instalados o ns-3 e o NetAnim e pode ser obtido a partir do seguinte link: https://193.136.212.206/irc/irc_vmware_ubuntu_20091111.tar.bz2. Para aceder mquina virtual utiliza-se o seguinte utilizador:
Username: irc Password: IRC$2009
Aps o download, a mquina virtual pode ser descompactada e atravs de um player para mquinas virtuais pode-se aceder ao ambiente j preparado. Para este efeito, sugere-se o uso do ambiente VMWare Player ou Sun VirtualBox. Conforme observado na Figura 1, para o incio da execuo a partir do player, basta escolher a pasta onde foi foi executado o desempacotamento. A partir desse ponto, uma nova sesso ter incio. Nessa sesso usar-se- as seguintes credenciais:
Username: ircuser Password: ircuser
IRC 2009/2010
Abaixo seguem links para documentao ns-3: NS-3 overview: http://www.nsnam.org/docs/ns-3-overview.pdf Tutoriais NS-3: http://www.nsnam.org/tutorials.html Documentao para as classes NS-3: http://www.nsnam.org/doxygen-release/index.html Introduo ao NS-3: http://www.nsnam.org/getting_started.html
4. Criao do primeiro script O ns-3 suporta scripts escritos nas linguagem C e Python. Neste exemplo, optou-se pela criao do script utilizando a linguagem Python.
4.1. Criao do cenrio O nosso cenrio ser composto por dois ns que vo comunicar utilizando o protocolo UDP. Neste exemplo, deve guardar o seu cdigo num ficheiro com o nome primeiro.py.
#Inicializa o modulo ns3 import ns3 #Activa os logs para os vrios componentes ns3.LogComponentEnable("UdpEchoClientApplication", ns3.LOG_LEVEL_INFO) ns3.LogComponentEnable("UdpEchoServerApplication", ns3.LOG_LEVEL_INFO) #Criao de dois ns nodes = ns3.NodeContainer() nodes.Create(2)
Node 0
Node 1
IRC 2009/2010
4.2. Criao do canal fsico de comunicao Neste momento o nosso cenrio tem dois ns mas, no entanto, no existe nenhum meio fsico para que esses mesmo ns possam comunicar. Vamos ento estabelecer a ligao fsica entre os ns.
#Criao de um objecto PointToPointHelper para a ligao ponto a ponto entre dois ns. pointToPoint = ns3.PointToPointHelper() #Definio das caracterstica da ligao pointToPoint.SetDeviceAttribute("DataRate", ns3.StringValue("10Mbps")) pointToPoint.SetChannelAttribute("Delay", ns3.StringValue("2ms")) #Instalao da ligao nos ns criados anteriormente devices = pointToPoint.Install(nodes)
A Figura 3 representa o estado actual do nosso cenrio. Neste momento j possumos os dois ns ligados atravs de uma ligao fsica.
Devices: NetDeviceContainer
Node 0
10Mpbs, 5ms
Node 1
4.3. Instalao do interface de rede Depois da ligao fsica, vamos agora criar os interfaces de rede para os vrios ns. Neste exemplo iremos utilizar uma stack IPv4(o ns-3 suporta tambm IPv6).
#Agrega as funcionalidades da stack TCP/IP aos ns stack = ns3.InternetStackHelper() stack.Install(nodes) #Criao do endereo IPv4 address = ns3.Ipv4AddressHelper() #Definio da rede e respectiva mascara de rede address.SetBase(ns3.Ipv4Address("192.168.1.0"), ns3.Ipv4Mask("255.255.255.0")) #Atribuio dos endereos aos respectivos ns #Como anteriormente foi definida a rede 192.168.1.0/255.255.255.0, os ns Node0 e Node1 vo ter os endereos 192.168.1.1 e 192.168.1.2, respectivamente interfaces = address.Assign(devices)
IRC 2009/2010
Neste momento temos todo o cenrio pronto at ao nvel da camada de rede. No entanto, no existem aplicaes a utilizar a nossa rede. Assim, necessrio criar uma aplicao. Neste exemplo vamos utilizar uma aplicao cliente-servidor, em que o cliente envia pacotes UDP ao servidor e o servidor responde ao cliente com uma cpia desse mesmo pacote.
#Cria uma aplicao que espera por pacotes UDP num determinado porto (neste caso o porto 5000, que passado como parmetro) e envia esse pacote para o remetente original echoServer = ns3.UdpEchoServerHelper(5000) #Instala a aplicao no servidor (i.e. no Node 1, que referenciado atravs da instruo nodes.Get(1)). serverApps = echoServer.Install(nodes.Get(1)) serverApps.Start(ns3.Seconds(1.0)) serverApps.Stop(ns3.Seconds(10.0)) #Cria uma aplicao que envia pacotes UDP e que espera pela resposta echoClient = ns3.UdpEchoClientHelper(interfaces.GetAddress(1), 5000) echoClient.SetAttribute("MaxPackets", ns3.UintegerValue(1)) echoClient.SetAttribute("Interval", ns3.TimeValue(ns3.Seconds (1.5))) echoClient.SetAttribute("PacketSize", ns3.UintegerValue(2048)) #Instala a aplicao anterior no n que ir actuar como remetente (i.e. Node 0) e em seguida inicia a mesma aplicao. clientApps = echoClient.Install(nodes.Get(0)) clientApps.Start(ns3.Seconds(1.5)) clientApps.Stop(ns3.Seconds(10.0))
4.5. Iniciar a simulao Depois da criao do cenrio e respectivas aplicaes, agora necessrio recorrer as primitivas que iro fazer com a simulao inicie e termine.
ns3.Simulator.Run() ns3.Simulator.Destroy()
Para correr a simulao dever colocar o ficheiro criado na pasta scratch na raiz do simulador e correr o seguinte comando:
./waf -pyrun scratch/primeiro.py
5. NetAnim Como mencionado anteriormente, em NS-3 ficheiros de trace no possuem o mesmo formato dos ficheiros produzidos em ns-2. Desta forma, tornou-se necessria uma aplicao que permitisse a leitura e gerasse animaes para ficheiros deste formato. A ferramenta NetAnim uma aplicao que d suporte execuo desta tarefa. Em nossa mquina virtual NetAnim j est instalada e pode ser automaticamente executada desde que o ficheiro de trace esteja no formato ns-3. IRC 2009/2010 5
Apresentaremos NetAnim atravs de um exemplo, disponvel tambm na mquina virtual usada nesta ficha. Aproveitamos para tambm apresentar as funcionalidades de ns-3 em linguagem C.
5.1. Captura dos parmetros iniciais
Para informar a aplicao dos valores dos parmetros (quantidade de ns na disposio esquerda e direita do plano) basta utilizar a seguinte instruo:
./waf --run 'src/contrib/net-anim/test-dumbbell --nLeftLeaf=5 --nRightLeaf=5 -animFile=dumbbell.tr'
Config::SetDefault ("ns3::OnOffApplication::PacketSize", UintegerValue (512)); Config::SetDefault ("ns3::OnOffApplication::DataRate", StringValue ("500kb/s")); uint32_t nLeftLeaf = 5; uint32_t nRightLeaf = 5; uint32_t nLeaf = 0; // Se diferente de zero o nmero de ns esquerdo e direito uint16_t port = 0; // Porto para onde se executa o bind dessa animao std::string animFile; // Nome que ser dado ao ficheiro de sada CommandLine cmd; cmd.AddValue ("nLeftLeaf", "Nmero de ns esquerda", nLeftLeaf); cmd.AddValue ("nRightLeaf","Nmero de ns direita", nRightLeaf); cmd.AddValue ("nLeaf", "Numero total de ns", nLeaf); cmd.AddValue ("port", "Porto para animao remota", port); cmd.AddValue ("animFile", "Nome do ficheiro de sada para posterior trace", animFile); cmd.Parse (argc,argv); if (nLeaf > 0) { nLeftLeaf = nLeaf; nRightLeaf = nLeaf; }
Da mesma forma que nos exemplos anteriores um objecto PointToPoint utilizado para se criarem as ligaes entre os ns, neste exemplo essas ligao so associadas a um objecto NetAnim PointToPointDumbellHelper.
PointToPointHelper pointToPointRouter; pointToPointRouter.SetDeviceAttribute ("DataRate", StringValue ("10Mbps")); pointToPointRouter.SetChannelAttribute ("Delay", StringValue ("1ms")); PointToPointHelper pointToPointLeaf; pointToPointLeaf.SetDeviceAttribute ("DataRate", StringValue ("10Mbps")); pointToPointLeaf.SetChannelAttribute ("Delay", StringValue ("1ms")); PointToPointDumbbellHelper d(nLeftLeaf, pointToPointLeaf, nRightLeaf, pointToPointLeaf, pointToPointRouter);
Endereamento e aplicao cliente O endereamento feito atravs de um objecto Ipv4AddressHelper. E a aplicao cliente, baseada em UDP, disparada e finalizada numa distribuio uniforme.
InternetStackHelper stack; d.InstallStack (stack);
IRC 2009/2010
d.AssignAddresses(Ipv4AddressHelper("10.1.1.0", "255.255.255.0"), Ipv4AddressHelper("10.2.1.0", "255.255.255.0"), Ipv4AddressHelper("10.3.1.0", "255.255.255.0")); OnOffHelper clientHelper ("ns3::UdpSocketFactory", Address ()); clientHelper.SetAttribute("OnTime", RandomVariableValue (UniformVariable (0, 1))); clientHelper.SetAttribute("OffTime", RandomVariableValue (UniformVariable (0, 1))); ApplicationContainer clientApps; for (uint32_t i = 0; i < d.RightCount(); ++i) { // Pacotes so gerados e enviados para o ns correspondente da direita AddressValue remoteAddress(InetSocketAddress(d.GetLeftAddress(i), 1000)); clientHelper.SetAttribute("Remote", remoteAddress); clientApps.Add(clientHelper.Install(d.GetRight(i))); } clientApps.Start (Seconds (0.0)); clientApps.Stop (Seconds (10.0)); // Configurao da area onde dar-se- a animao d.BoundingBox(1, 1, 10, 10);
O NetAnim possui uma classe que permite a configurao da animao da simulao a classe AnimationInterface. A partir de um objecto desta classe inicia-se a visualizao desta simulao.
AnimationInterface anim; if (port > 0) { anim.SetServerPort(port); } else if (!animFile.empty()) { anim.SetOutputFile(animFile); } anim.StartAnimation(); Ipv4GlobalRoutingHelper::PopulateRoutingTables (); std::cout << "Running the simulation" << std::endl; Simulator::Run (); std::cout << "Destroying the simulation" << std::endl; Simulator::Destroy (); std::cout << "Stopping the animation" << std::endl; anim.StopAnimation();
5.4. Resultados
Os resultados so animaes similares s previamente obtidas em ns-2, conforme observa-se na Figura 4. O resultado da Figura 4 automaticamente obtido a partir da execuo da instruo NetAnim dumbbell.tr.
IRC 2009/2010
6. Segundo script
Neste segundo exemplo vamos explorar o uso de sockets em conjunto com o protocolo TCP. Criaremos uma topologia simples, como pode ser observado na Figura 5. Nosso intuito enviar pacotes at um tamanho mximo (estipulado no script) de forma que o n n2 j no possa mais responder ao n requisitante (n 0).
NodeContainer n0n1; n0n1.Create (2); NodeContainer n1n2; n1n2.Add (n0n1.Get (1)); n1n2.Create (1);
/* Assim como no script anterior, lanamos mo de PointToPointHelper para criar o canal de comunicao que vai abrigar os ns criados anteriormente */
IRC 2009/2010
PointToPointHelper p2p; p2p.SetDeviceAttribute ("DataRate", DataRateValue (DataRate(10000000))); p2p.SetChannelAttribute ("Delay", TimeValue (MilliSeconds(10)));
/* Embora tenhamos criados os ns, estes ainda no foram associados a nenhum tipo de dispositivo. Dessa forma cada container de ns torna-se um container de dispositivos de rede, podendo, posteriormente incorporar caractersticas tpicas destes dipositivos */
6.2. Incorporao da pilha de protocolos TCP/IP Para que quaisquer testes possam ser feitos, necessrio associar endereos e os comportamentos associados aos protocolos dessa pilha. Para que o teste possa ser feito cada um dos ns estar associado a um endereo IP.
//As seguintes instrues instala a pilha de protocolos TCP/IP em todos os ns
Ipv4AddressHelper ipv4; ipv4.SetBase ("10.1.3.0", "255.255.255.0"); ipv4.Assign (dev0); ipv4.SetBase ("10.1.2.0", "255.255.255.0"); Ipv4InterfaceContainer ipInterfs = ipv4.Assign (dev1);
//Para que ambos conjuntos de endereos sejam alcanveis, popula-se as tabelas de roteamento
Ipv4GlobalRoutingHelper::PopulateRoutingTables ();
6.3. Definio dos comportamentos esperados para os ns Conforme descrito anteriormente, o n n2 comportar-se- como um terminador das requisies. Para tanto, associa-se a esse n um objecto PacketSinkHelper. Por outro lado, por se tratar de um cenrio baseado no protocolo TCP, o requisitante (n1) passa a estar associado a um socket para onde n2 confirma as requisies efectuadas.
ApplicationContainer apps = sink.Install (n1n2.Get (1)); apps.Start (Seconds (0.0)); apps.Stop (Seconds (3.0));
/* Agora devemos criar uma fonte para o envio de pacotes a partir de n0. A criao do socket e a associao ao n n0 permitir nossa aplicao identificar o endereo para onde encaminhar a resposta a alguma requisio. */
IRC 2009/2010
/* Para simular o envio de requisies uma nova funo foi criada StartFlow. Essa funo disparada quando do incio da simulao (Simulator::ScheduleNow). */
6.4. Implementao do envio de pacotes Conforme mencionado anteriormente, espera-se que o n n2 receba requisies do n n0. Essas requisies devem cessar quando atingirem um limite mximo (2000000 bytes). Para explicar como o envio foi produzido e o limite testado, esta etapa foi dividida em duas subetapas: definio dos elementos bsicos para envio e teste do tamanho dos pacotes e posteriormente as funes.
Elementos bsicos para o envio e teste // limite mximo de bytes que se pretende enviar static const uint32_t totalTxBytes = 2000000; static uint32_t currentTxBytes = 0; static const uint32_t writeSize = 1040; //buffer do n n0 de onde sero enviados dados para o n n2 uint8_t data[writeSize]; /* Para efeitos de teste, algum contedo colocado em data para que possa ser enviado ao n n2 */ for(uint32_t i = 0; i < writeSize; ++i) { char m = toascii (97 + i % 26); data[i] = m; } Funes
void StartFlow(Ptr<Socket> localSocket,Ipv4Address servAddress, uint16_t servPort) { // o socket que foi enviado automaticamente conectado ao servidor localSocket->Connect (InetSocketAddress (servAddress, servPort)); /* Sucessivas chamadas sero feitas e logo aps um teste da quantidade de informao enviada feito, dessa forma, quando atingir-se o limite esperado, as chamadas so cessadas. */ localSocket->SetSendCallback (MakeCallback (&WriteUntilBufferFull)); WriteUntilBufferFull (localSocket, localSocket->GetTxAvailable ()); } /* o buffer (data) previamente ocupado com algum contedo, ser constantemente utilizado. Essa funo retornar o fim da conexo socket ao n n0 assim que a quantidade de bytes enviada atingir o valor totalTxBytes e j no houver dados a serem enviados para o n n2. */ void WriteUntilBufferFull (Ptr<Socket> localSocket, uint32_t txSpace) { while (currentTxBytes < totalTxBytes && localSocket->GetTxAvailable () > 0) { uint32_t left = totalTxBytes - currentTxBytes; uint32_t dataOffset = currentTxBytes % writeSize; uint32_t toWrite = writeSize - dataOffset; toWrite = std::min (toWrite, left); toWrite = std::min (toWrite, localSocket->GetTxAvailable ()); int amountSent = localSocket->Send (&data[dataOffset], toWrite, 0); if(amountSent < 0) { return; } currentTxBytes += amountSent; } localSocket->Close (); }
IRC 2009/2010
10
Ainda torna-se necessrio definir em que formato o resultado dessa simulao vai ser averiguada. Como dito anteriormente, o ns-3 d a possibilidade de desviar o comportamento das topologias de teste para ficheiros pcap, ou seja, permite a monitorizao dos pacotes em modo promscuo, o qual pode posteriormente ser analisado por um analisador de trfego como o Wiresharck. Para que esse script pudesse comportar-se dessa forma, as seguintes instrues foram adicionadas ao script.
// uma alternativa para monitorizar o trfego atravs de um ficheiro de trace std::ofstream ascii; ascii.open ("segundo.tr"); PointToPointHelper::EnableAsciiAll (ascii); /* o canal previamente estabelecido pode ser colocado em modo promscuo de forma que toda comunicao possa ser monitorizada e armazenada em ficheiros no formato segundo-XX.pcap */ PointToPointHelper::EnablePcapAll ("segundo"); /* Apenas para resguardar de possveis falhas o simulador fora uma parada a um determinado momento para o caso de nunca atingir-se o limite de bytes estipulado. */ Simulator::Stop (Seconds(1000)); Simulator::Run (); Simulator::Destroy ();
Como parte da avaliao do resultado, pode-se utilizar do Wireshark para averiguar todo o trfego do segundo script que foi direccionado para ficheiros pcap. Observe pela Figura 6 que como tratase de uma aplicao TCP inmeros acknowledgments foram necessrios.
Figura 6 - Captura dos primeiros pacotes enviados pelo segundo script no Wireshark.
IRC 2009/2010
11