Analysis stage
authorRichard Whitehouse <github@richardwhiuk.com>
Tue, 17 May 2011 19:51:04 +0000 (20:51 +0100)
committerRichard Whitehouse <github@richardwhiuk.com>
Tue, 17 May 2011 19:51:04 +0000 (20:51 +0100)
src/simulation/analysis.cc [new file with mode: 0644]
src/simulation/model/analysis.cc [new file with mode: 0644]
src/simulation/model/analysis.h [new file with mode: 0644]
src/simulation/wscript

diff --git a/src/simulation/analysis.cc b/src/simulation/analysis.cc
new file mode 100644 (file)
index 0000000..56ed4ef
--- /dev/null
@@ -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 <ns3@richardwhiuk.com>
+ */
+
+#include "ns3/core-module.h"
+#include "ns3/topology-module.h"
+#include "ns3/simulation-module.h"
+
+#include <stdexcept>
+#include <iostream>
+#include <fstream>
+
+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 (file)
index 0000000..90f7631
--- /dev/null
@@ -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 <ns3@richardwhiuk.com>
+ */
+
+#include "analysis.h"
+#include "ns3/object.h"
+#include "ns3/log.h"
+
+#include <assert.h>
+
+#include <stdexcept>
+#include <iostream>
+#include <fstream>
+
+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<csmaParse>::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<std::string,std::map<std::string,std::string> >::iterator vit = it->packet.begin(); vit != it->packet.end(); ++vit){
+                       std::cout << '\t' << vit->first << std::endl;
+                       for(std::map<std::string, std::string>::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<csmaParse>::iterator it = traces.begin(); it != traces.end(); ++it){
+               std::map<std::string, std::map<std::string, std::string> >::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<std::pair<std::string, std::string> >::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<std::string, std::string> 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 (file)
index 0000000..7eb86e8
--- /dev/null
@@ -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 <ns3@richardwhiuk.com>
+ */
+
+#ifndef SIMULATION_ANALYSIS
+#define SIMULATION_ANALYSIS
+
+#include "ns3/topology.h"
+
+#include <stdexcept>
+#include <iostream>
+#include <fstream>
+#include <vector>
+#include <string>
+#include <map>
+
+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<std::string,std::map<std::string,std::string> > 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<csmaParse> traces;
+
+       Topology topology;
+
+       std::istream& data;
+       std::istream& csma;
+       std::istream& state;
+
+       std::ostream& output;
+       std::ostream& dot;
+       std::ostream& graph;
+
+       bool moose;
+
+};
+
+}
+
+#endif
+
index 3f614c42b9ed2783e54ea40a01f1705cadde4e51..d7025c8884f213217c2b48505cef6a15423673e4 100644 (file)
@@ -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'