From 749e7a201e54390de8fef60513f9f3c3fe1cc86f Mon Sep 17 00:00:00 2001 From: Richard Whitehouse Date: Tue, 17 May 2011 20:51:04 +0100 Subject: [PATCH] Analysis stage --- src/simulation/analysis.cc | 137 ++++++++++++++++ src/simulation/model/analysis.cc | 263 +++++++++++++++++++++++++++++++ src/simulation/model/analysis.h | 94 +++++++++++ src/simulation/wscript | 9 +- 4 files changed, 501 insertions(+), 2 deletions(-) create mode 100644 src/simulation/analysis.cc create mode 100644 src/simulation/model/analysis.cc create mode 100644 src/simulation/model/analysis.h diff --git a/src/simulation/analysis.cc b/src/simulation/analysis.cc new file mode 100644 index 0000000..56ed4ef --- /dev/null +++ b/src/simulation/analysis.cc @@ -0,0 +1,137 @@ +/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */ +/* + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation; + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * + * Author: Richard Whitehouse + */ + +#include "ns3/core-module.h" +#include "ns3/topology-module.h" +#include "ns3/simulation-module.h" + +#include +#include +#include + +using namespace ns3; + +NS_LOG_COMPONENT_DEFINE ("MooseAnalysis"); + +int main (int argc, char *argv[]) +{ + +try { + + std::string topology; + std::string data; + std::string csma; + std::string state; + std::string link = "ethernet"; + std::string output; + std::string dot; + std::string graph; + + { + CommandLine cmd; // Allow CommandLine args + cmd.AddValue("topology", "Network topology", topology); + cmd.AddValue("data", "Network data", data); + cmd.AddValue("csma", "Network trace", csma); + cmd.AddValue("state", "Bridge state", state); + cmd.AddValue("link", "Link layer used (moose|ethernet) [ethernet]", link); + cmd.AddValue("output", "Output file of analysis", output); + cmd.AddValue("dot", ".dot file shwoing topology", dot); + cmd.AddValue("graph", "gnuplot data file", graph); + cmd.Parse (argc, argv); + } + + // Setup streams + + std::ifstream topologyStream(topology.c_str(), std::ios_base::in); + std::ifstream dataStream(data.c_str(), std::ios_base::in); + std::ifstream csmaStream(csma.c_str(), std::ios_base::in); + std::ifstream stateStream(state.c_str(), std::ios_base::in); + + std::ofstream outputStream(output.c_str(), std::ios_base::out | std::ios_base::trunc); + std::ofstream dotStream(dot.c_str(), std::ios_base::out | std::ios_base::trunc); + std::ofstream graphStream(graph.c_str(), std::ios_base::out | std::ios_base::trunc); + + // Check streams + + if(topologyStream.fail()){ + std::ostringstream ss; + ss << "Failed to open network topology file [" << topology << "]"; + throw new std::runtime_error(ss.str()); + } + + if(dataStream.fail()){ + std::ostringstream ss; + ss << "Failed to open network data file [" << data << "]"; + throw new std::runtime_error(ss.str()); + } + + if(csmaStream.fail()){ + std::ostringstream ss; + ss << "Failed to open network trace file [" << csma << "]"; + throw new std::runtime_error(ss.str()); + } + + if(stateStream.fail()){ + std::ostringstream ss; + ss << "Failed to open network state file [" << data << "]"; + throw new std::runtime_error(ss.str()); + } + + if(outputStream.fail()){ + std::ostringstream ss; + ss << "Failed to open output file [" << output << "]"; + throw new std::runtime_error(ss.str()); + } + + if(dotStream.fail()){ + std::ostringstream ss; + ss << "Failed to open dot file [" << dot << "]"; + throw new std::runtime_error(ss.str()); + } + + if(graphStream.fail()){ + std::ostringstream ss; + ss << "Failed to open graph data file [" << graph << "]"; + throw new std::runtime_error(ss.str()); + } + + bool moose; + + if(link == "moose"){ + moose = true; + } else if(link == "ethernet") { + moose = false; + } else { + std::ostringstream ss; + ss << "Unknown link layer: [" << link << "]"; + throw new std::runtime_error(ss.str()); + } + + // Analysis + + Analysis a(topologyStream, dataStream, csmaStream, stateStream, outputStream, dotStream, graphStream, moose); + +} catch(std::runtime_error* e) { + std::cerr << e->what() << std::endl; + return 1; +} + +return 0; + +} + diff --git a/src/simulation/model/analysis.cc b/src/simulation/model/analysis.cc new file mode 100644 index 0000000..90f7631 --- /dev/null +++ b/src/simulation/model/analysis.cc @@ -0,0 +1,263 @@ +/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */ +/* + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation; + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * + * Author: Richard Whitehouse + */ + +#include "analysis.h" +#include "ns3/object.h" +#include "ns3/log.h" + +#include + +#include +#include +#include + +NS_LOG_COMPONENT_DEFINE ("Analysis"); + +namespace ns3 { + +Analysis::Analysis(std::istream& topology, std::istream& data, std::istream& csma, std::istream& state, std::ostream& output, std::ostream& dot, std::ostream& graph, bool moose) : topology(topology), data(data), csma(csma), state(state), output(output), dot(dot), graph(graph), moose(moose){ + + parseCsma(); + + analyseCsma(); + + generateDot(); + +} + +Analysis::~Analysis(){ + +} + +void Analysis::printCsma(){ + long i = 0; + for(std::vector::iterator it = traces.begin(); it != traces.end(); ++it, ++i){ + std::cout << "[" << i << "]" << std::endl; + std::cout << '\t' << it->type << std::endl; + std::cout << '\t' << it->time << std::endl; + std::cout << '\t' << it->node << std::endl; + for(std::map >::iterator vit = it->packet.begin(); vit != it->packet.end(); ++vit){ + std::cout << '\t' << vit->first << std::endl; + for(std::map::iterator mit = vit->second.begin(); mit != vit->second.end(); ++mit){ + std::cout << "\t\t" << mit->first << '\t' << mit->second << std::endl; + } + } + } + +} + +void Analysis::generateDot(){ + dot << "graph G { " << std::endl; + dot << "node [shape=box, style=filled];" << std::endl; + for(long i = 0; i < topology.bridges; ++i){ + dot << "S" << i << ";" << std::endl; + } + dot << "node [shape=circle, style=filled];" << std::endl; + for(long i = 0; i < topology.hosts; ++i){ + dot << "H" << i << ";" << std::endl; + } + dot << "edge [len=1];" << std::endl; + for(Topology::HostLinks::iterator it = topology.hostLinks.begin(); it != topology.hostLinks.end(); ++it){ + dot << "H" << it->first << " -- S" << it->second << "; " << std::endl; + } + dot << "edge [len=2];" << std::endl; + for(Topology::BridgeLinks::iterator it = topology.bridgeLinks.begin(); it != topology.bridgeLinks.end(); ++it){ + dot << "S" << it->first << " -- S" << it->second << "; " << std::endl; + } + dot << "}" << std::endl; + +} + +void Analysis::parseCsma(){ + std::string line; + while(!csma.eof()){ + getline(csma, line); + if(line.size() > 0){ + parseCsmaLine(line); + } + } +} + +void Analysis::analyseCsma(){ + + for(std::vector::iterator it = traces.begin(); it != traces.end(); ++it){ + std::map >::iterator mit; + if((mit = it->packet.find("ns3::ArpHeader")) != it->packet.end()){ + if(it->type == "+"){ + ++(arp.added); + } else if(it->type == "-"){ + ++(arp.removed); + } else if(it->type == "r"){ + ++(arp.received); + } + + } else if( + ((mit = it->packet.find("ns3::Ipv4Header")) != it->packet.end()) + && + ((mit = it->packet.find("ns3::UdpHeader")) != it->packet.end()) + ) { + if(it->type == "+"){ + ++(udp.added); + } else if(it->type == "-"){ + ++(udp.removed); + } else if(it->type == "r"){ + ++(udp.received); + } + } else { + mit = it->packet.begin(); ++mit; + std::cout << mit->first << std::endl; + assert(false); + } + + if(it->packet["ns3::EthernetHeader"]["destination"] == "ff:ff:ff:ff:ff:ff"){ + if(it->type == "+"){ + ++(broadcast.added); + } else if(it->type == "-"){ + ++(broadcast.removed); + } else if(it->type == "r"){ + ++(broadcast.received); + } + } else { + if(it->type == "+"){ + ++(unicast.added); + } else if(it->type == "-"){ + ++(unicast.removed); + } else if(it->type == "r"){ + ++(unicast.received); + } + } + + if(it->type == "+"){ + ++(total.added); + } else if(it->type == "-"){ + ++(total.removed); + } else if(it->type == "r"){ + ++(total.received); + } else { + std::cout << it->type << std::endl; + assert(false); + } + } + + std::cout << "ARP +: " << arp.added << " -: " << arp.removed << " r: " << arp.received << std::endl; + std::cout << "UDP +: " << udp.added << " -: " << udp.removed << " r: " << udp.received << std::endl; + + std::cout << "UCa +: " << unicast.added << " -: " << unicast.removed << " r: " << unicast.received << std::endl; + std::cout << "BCa +: " << broadcast.added << " -: " << broadcast.removed << " r: " << broadcast.received << std::endl; + + std::cout << "Total +: " << total.added << " -: " << total.removed << " r: " << total.received << std::endl; + + + //std::vector >::iterator hit; + +} + +void Analysis::parseCsmaLine(std::string& line){ + csmaParse parse; + size_t spaa, spab, spac, spad; + size_t dend, dsta, dstb, dmid; + size_t sepa, sepb; + + // type sepa time sepb node sepc { header sepd line + + spaa = line.find(' '); + parse.type = line.substr(0, spaa); + spab = line.find(' ', spaa + 1); + parse.time = line.substr(spaa + 1, spab - spaa - 1); + spac = line.find(' ', spab + 1); + parse.node = line.substr(spab + 1, spac - spab - 1); + + while(spac != std::string::npos){ + std::string header; + std::map data; + + spad = line.find(' ', spac + 1); + header = line.substr(spac + 1, spad - spac - 1); + + dsta = line.find('(', spad + 1); + dstb = line.find(' ', dsta + 1); + dsta = (dstb == (dsta + 1)) ? dstb : dsta; + + dend = line.find(')', dsta + 1); + + dmid = dsta; + + while(dmid < dend){ + + std::string key; + + sepa = line.find('=', dmid + 1); + + if(sepa <= dend){ + key = line.substr(dmid + 1, sepa - dmid - 1); + + sepb = line.find(',', sepa + 1); + if(sepb <= dend){ + data[key] = line.substr(sepa + 1, sepb - sepa - 1); + dmid = sepb + 1; + } else { + data[key] = line.substr(sepa + 1, dend - sepa - 1); + dmid = dend; + } + } else { + sepa = line.find(": ", dmid + 1); + + if(sepa <= dend){ + + key = line.substr(dmid + 1, sepa - dmid - 1); + + sepb = line.find(' ', sepa + 2); + + if(sepb <= dend){ + data[key] = line.substr(sepa + 2, sepb - sepa - 2); + dmid = sepb; + } else { + data[key] = line.substr(sepa + 2, dend - sepa - 2); + dmid = dend; + } + + } else { + + data["route"] = line.substr(dmid + 1, dend - dmid - 1); + + dmid = dend; + + } + + } + + + + } + + spac = line.find(' ', dend + 1); + + if(parse.packet.find(header) != parse.packet.end()){ + std::cout << line << std::endl; + } + + parse.packet[header] = data; + + } + + traces.push_back(parse); + +} + +} + diff --git a/src/simulation/model/analysis.h b/src/simulation/model/analysis.h new file mode 100644 index 0000000..7eb86e8 --- /dev/null +++ b/src/simulation/model/analysis.h @@ -0,0 +1,94 @@ +/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */ +/* + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation; + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * + * Author: Richard Whitehouse + */ + +#ifndef SIMULATION_ANALYSIS +#define SIMULATION_ANALYSIS + +#include "ns3/topology.h" + +#include +#include +#include +#include +#include +#include + +namespace ns3 { + +class Analysis { + +public: + + Analysis(std::istream& topology, std::istream& data, std::istream& csma, std::istream& state, std::ostream& output, std::ostream& dot, std::ostream& graph, bool moose); + virtual ~Analysis(); + +protected: + + void generateDot(); + void analyseCsma(); + void printCsma(); + void parseCsma(); + void parseCsmaLine(std::string& line); + +private: + + struct csmaParse { + std::string type; + std::string time; + std::string node; + std::map > packet; + }; + + struct csmaAnalysis { + + csmaAnalysis() : added(0), removed(0), received(0){ + + } + + long added; + long removed; + long received; + }; + + csmaAnalysis arp; + csmaAnalysis udp; + csmaAnalysis total; + + csmaAnalysis broadcast; + csmaAnalysis unicast; + + std::vector traces; + + Topology topology; + + std::istream& data; + std::istream& csma; + std::istream& state; + + std::ostream& output; + std::ostream& dot; + std::ostream& graph; + + bool moose; + +}; + +} + +#endif + diff --git a/src/simulation/wscript b/src/simulation/wscript index 3f614c4..d7025c8 100644 --- a/src/simulation/wscript +++ b/src/simulation/wscript @@ -4,18 +4,23 @@ def build(bld): mod = bld.create_ns3_module('simulation') mod.source = [ + 'model/analysis.cc', ] headers = bld.new_task_gen('ns3header') headers.module = 'simulation' - headers.source = [] + headers.source = [ + 'model/analysis.h', + ] + obj = bld.create_ns3_program('analysis', ['bridge', 'topology','simulation']) + + obj.source = 'analysis.cc' obj = bld.create_ns3_program('generator', ['bridge', 'internet-stack']) obj.source = 'generator.cc' - obj = bld.create_ns3_program('simulation', ['bridge', 'internet-stack']) obj.source = 'simulation.cc' -- 2.34.1