PageRenderTime 35ms CodeModel.GetById 28ms RepoModel.GetById 1ms app.codeStats 0ms

/src/contrib/topology-read/rocketfuel-topology-reader.cc

https://github.com/annegabrielle/secure_adhoc_network_ns-3
C++ | 490 lines | 379 code | 76 blank | 35 comment | 71 complexity | ee87e1b6eaf4a16e13cf21b36867ff14 MD5 | raw file
  1. /* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
  2. /*
  3. * Copyright (c) 2010 Hajime Tazaki
  4. *
  5. * This program is free software; you can redistribute it and/or modify
  6. * it under the terms of the GNU General Public License version 2 as
  7. * published by the Free Software Foundation;
  8. *
  9. * This program is distributed in the hope that it will be useful,
  10. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  11. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  12. * GNU General Public License for more details.
  13. *
  14. * You should have received a copy of the GNU General Public License
  15. * along with this program; if not, write to the Free Software
  16. * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
  17. *
  18. * Author: Hajime Tazaki (tazaki@sfc.wide.ad.jp)
  19. */
  20. #include <fstream>
  21. #include <cstdlib>
  22. #include <iostream>
  23. #include <sstream>
  24. #include <regex.h>
  25. #include "ns3/log.h"
  26. #include "rocketfuel-topology-reader.h"
  27. namespace ns3 {
  28. NS_LOG_COMPONENT_DEFINE ("RocketfuelTopologyReader");
  29. NS_OBJECT_ENSURE_REGISTERED (RocketfuelTopologyReader);
  30. TypeId RocketfuelTopologyReader::GetTypeId (void)
  31. {
  32. static TypeId tid = TypeId ("ns3::RocketfuelTopologyReader")
  33. .SetParent<Object> ()
  34. ;
  35. return tid;
  36. }
  37. RocketfuelTopologyReader::RocketfuelTopologyReader ()
  38. {
  39. NS_LOG_FUNCTION (this);
  40. }
  41. RocketfuelTopologyReader::~RocketfuelTopologyReader ()
  42. {
  43. NS_LOG_FUNCTION (this);
  44. }
  45. /* uid @loc [+] [bb] (num_neigh) [&ext] -> <nuid-1> <nuid-2> ... {-euid} ... =name[!] rn */
  46. #define REGMATCH_MAX 16
  47. #define START "^"
  48. #define END "$"
  49. #define SPACE "[ \t]+"
  50. #define MAYSPACE "[ \t]*"
  51. #define ROCKETFUEL_MAPS_LINE \
  52. START "(-*[0-9]+)" SPACE "(@[?A-Za-z0-9,+]+)" SPACE \
  53. "(\\+)*" MAYSPACE "(bb)*" MAYSPACE \
  54. "\\(([0-9]+)\\)" SPACE "(&[0-9]+)*" MAYSPACE \
  55. "->" MAYSPACE "(<[0-9 \t<>]+>)*" MAYSPACE \
  56. "(\\{-[0-9\\{\\} \t-]+\\})*" SPACE \
  57. "=([A-Za-z0-9.!-]+)" SPACE "r([0-9])" \
  58. MAYSPACE END
  59. #define ROCKETFUEL_WEIGHTS_LINE \
  60. START "([^ \t]+)" SPACE "([^ \t]+)" SPACE "([0-9.]+)" MAYSPACE END
  61. int linksNumber = 0;
  62. int nodesNumber = 0;
  63. std::map<std::string, Ptr<Node> > nodeMap;
  64. NodeContainer
  65. RocketfuelTopologyReader::GenerateFromMapsFile (int argc, char *argv[])
  66. {
  67. std::string uid;
  68. std::string loc;
  69. std::string ptr;
  70. std::string name;
  71. std::string nuid;
  72. bool dns = false;
  73. bool bb = false;
  74. int num_neigh = 0;
  75. int ext_conn = 0;
  76. int radius = 0;
  77. std::vector <std::string> neigh_list;
  78. NodeContainer nodes;
  79. uid = argv[0];
  80. loc = argv[1];
  81. if (argv[2])
  82. dns = true;
  83. if (argv[3])
  84. bb = true;
  85. num_neigh = ::atoi (argv[4]);
  86. /* the first char should be '&' */
  87. if (argv[5])
  88. {
  89. ext_conn = ::atoi (&argv[5][1]);
  90. }
  91. /* neighbors */
  92. if (argv[6])
  93. {
  94. char *nbr;
  95. char *stringp = argv[6];
  96. while ((nbr = strsep (&stringp, " \t")) != NULL)
  97. {
  98. nbr[strlen (nbr) - 1] = '\0';
  99. neigh_list.push_back (nbr + 1);
  100. }
  101. }
  102. /* externs */
  103. if (argv[7])
  104. {
  105. // euid = argv[7];
  106. }
  107. /* name */
  108. if (argv[8])
  109. {
  110. name = argv[8];
  111. }
  112. radius = ::atoi (&argv[9][1]);
  113. if (radius > 0)
  114. {
  115. return nodes;
  116. }
  117. /* uid @loc [+] [bb] (num_neigh) [&ext] -> <nuid-1> <nuid-2> ... {-euid} ... =name[!] rn */
  118. NS_LOG_INFO ("Load Node[" << uid << "]: location: " << loc << " dns: " << dns
  119. << " bb: " << bb << " neighbors: " << neigh_list.size ()
  120. << "(" << "%d" << ") externals: \"%s\"(%d) "
  121. << "name: " << name << " radius: " << radius);
  122. // Create node and link
  123. if (!uid.empty ())
  124. {
  125. if (nodeMap[uid] == 0)
  126. {
  127. Ptr<Node> tmpNode = CreateObject<Node> ();
  128. nodeMap[uid] = tmpNode;
  129. nodes.Add (tmpNode);
  130. nodesNumber++;
  131. }
  132. for (uint32_t i = 0; i < neigh_list.size (); ++i)
  133. {
  134. nuid = neigh_list[i];
  135. if (nuid.empty ())
  136. {
  137. return nodes;
  138. }
  139. if (nodeMap[nuid] == 0)
  140. {
  141. Ptr<Node> tmpNode = CreateObject<Node> ();
  142. nodeMap[nuid] = tmpNode;
  143. nodes.Add (tmpNode);
  144. nodesNumber++;
  145. }
  146. NS_LOG_INFO (linksNumber << ":" << nodesNumber << " From: " << uid << " to: " << nuid);
  147. Link link (nodeMap[uid], uid, nodeMap[nuid], nuid);
  148. AddLink (link);
  149. linksNumber++;
  150. }
  151. }
  152. return nodes;
  153. }
  154. NodeContainer
  155. RocketfuelTopologyReader::GenerateFromWeightsFile (int argc, char *argv[])
  156. {
  157. /* uid @loc [+] [bb] (num_neigh) [&ext] -> <nuid-1> <nuid-2> ... {-euid} ... =name[!] rn */
  158. std::string sname;
  159. std::string tname;
  160. double weight;
  161. char *endptr;
  162. NodeContainer nodes;
  163. sname = argv[0];
  164. tname = argv[1];
  165. weight = strtod (argv[2], &endptr);
  166. if (*endptr != '\0')
  167. {
  168. NS_LOG_WARN ("invalid weight: " << argv[2]);
  169. return nodes;
  170. }
  171. // Create node and link
  172. if (!sname.empty () && !tname.empty ())
  173. {
  174. if (nodeMap[sname] == 0)
  175. {
  176. Ptr<Node> tmpNode = CreateObject<Node> ();
  177. nodeMap[sname] = tmpNode;
  178. nodes.Add (tmpNode);
  179. nodesNumber++;
  180. }
  181. if (nodeMap[tname] == 0)
  182. {
  183. Ptr<Node> tmpNode = CreateObject<Node> ();
  184. nodeMap[tname] = tmpNode;
  185. nodes.Add (tmpNode);
  186. nodesNumber++;
  187. }
  188. NS_LOG_INFO (linksNumber << ":" << nodesNumber << " From: " << sname << " to: " << tname);
  189. TopologyReader::ConstLinksIterator iter;
  190. bool found = false;
  191. for (iter = LinksBegin (); iter != LinksEnd (); iter++)
  192. {
  193. if ((iter->GetFromNode () == nodeMap[tname]) &&
  194. (iter->GetToNode () == nodeMap[sname]))
  195. {
  196. found = true;
  197. break;
  198. }
  199. }
  200. if (!found)
  201. {
  202. Link link (nodeMap[sname], sname, nodeMap[tname], tname);
  203. AddLink (link);
  204. linksNumber++;
  205. }
  206. }
  207. return nodes;
  208. }
  209. enum RocketfuelTopologyReader::RF_FileType
  210. RocketfuelTopologyReader::GetFileType (const char *line)
  211. {
  212. int ret;
  213. regmatch_t regmatch[REGMATCH_MAX];
  214. regex_t regex;
  215. char errbuf[512];
  216. // Check whether MAPS file or not
  217. ret = regcomp (&regex, ROCKETFUEL_MAPS_LINE, REG_EXTENDED|REG_NEWLINE);
  218. if (ret != 0)
  219. {
  220. regerror (ret, &regex, errbuf, sizeof (errbuf));
  221. return RF_UNKNOWN;
  222. }
  223. ret = regexec (&regex, line, REGMATCH_MAX, regmatch, 0);
  224. if (ret != REG_NOMATCH)
  225. {
  226. regfree (&regex);
  227. return RF_MAPS;
  228. }
  229. regfree (&regex);
  230. // Check whether Weights file or not
  231. ret = regcomp (&regex, ROCKETFUEL_WEIGHTS_LINE, REG_EXTENDED|REG_NEWLINE);
  232. if (ret != 0)
  233. {
  234. regerror (ret, &regex, errbuf, sizeof (errbuf));
  235. return RF_UNKNOWN;
  236. }
  237. ret = regexec (&regex, line, REGMATCH_MAX, regmatch, 0);
  238. if (ret != REG_NOMATCH)
  239. {
  240. regfree (&regex);
  241. return RF_WEIGHTS;
  242. }
  243. regfree (&regex);
  244. return RF_UNKNOWN;
  245. }
  246. NodeContainer
  247. RocketfuelTopologyReader::Read (void)
  248. {
  249. std::ifstream topgen;
  250. topgen.open (GetFileName ().c_str ());
  251. NodeContainer nodes;
  252. std::istringstream lineBuffer;
  253. std::string line;
  254. int lineNumber = 0;
  255. enum RF_FileType ftype = RF_UNKNOWN;
  256. char errbuf[512];
  257. if (!topgen.is_open ())
  258. {
  259. NS_LOG_WARN ("Couldn't open the file " << GetFileName ());
  260. return nodes;
  261. }
  262. while (!topgen.eof ())
  263. {
  264. int ret;
  265. int argc;
  266. char *argv[REGMATCH_MAX];
  267. char *buf;
  268. lineNumber++;
  269. line.clear ();
  270. lineBuffer.clear ();
  271. getline (topgen, line);
  272. buf = (char *)line.c_str ();
  273. if (lineNumber == 1)
  274. {
  275. ftype = GetFileType (buf);
  276. if (ftype == RF_UNKNOWN)
  277. {
  278. NS_LOG_INFO ("Unknown File Format (" << GetFileName () << ")");
  279. break;
  280. }
  281. }
  282. regmatch_t regmatch[REGMATCH_MAX];
  283. regex_t regex;
  284. if (ftype == RF_MAPS)
  285. {
  286. ret = regcomp (&regex, ROCKETFUEL_MAPS_LINE, REG_EXTENDED|REG_NEWLINE);
  287. if (ret != 0)
  288. {
  289. regerror (ret, &regex, errbuf, sizeof (errbuf));
  290. regfree (&regex);
  291. break;
  292. }
  293. ret = regexec (&regex, buf, REGMATCH_MAX, regmatch, 0);
  294. if (ret == REG_NOMATCH)
  295. {
  296. NS_LOG_WARN ("match failed (maps file): %s" << buf);
  297. regfree (&regex);
  298. break;
  299. }
  300. }
  301. else if (ftype == RF_WEIGHTS)
  302. {
  303. ret = regcomp (&regex, ROCKETFUEL_WEIGHTS_LINE, REG_EXTENDED|REG_NEWLINE);
  304. if (ret != 0)
  305. {
  306. regerror (ret, &regex, errbuf, sizeof (errbuf));
  307. regfree (&regex);
  308. break;
  309. }
  310. ret = regexec (&regex, buf, REGMATCH_MAX, regmatch, 0);
  311. if (ret == REG_NOMATCH)
  312. {
  313. NS_LOG_WARN ("match failed (weights file): %s" << buf);
  314. regfree (&regex);
  315. break;
  316. }
  317. }
  318. line = buf;
  319. argc = 0;
  320. /* regmatch[0] is the entire strings that matched */
  321. for (int i = 1; i < REGMATCH_MAX; i++)
  322. {
  323. if (regmatch[i].rm_so == -1)
  324. {
  325. argv[i-1] = NULL;
  326. }
  327. else
  328. {
  329. line[regmatch[i].rm_eo] = '\0';
  330. argv[i-1] = &line[regmatch[i].rm_so];
  331. argc = i;
  332. }
  333. }
  334. if (ftype == RF_MAPS)
  335. {
  336. nodes.Add (GenerateFromMapsFile (argc, argv));
  337. }
  338. else if (ftype == RF_WEIGHTS)
  339. {
  340. nodes.Add (GenerateFromWeightsFile (argc, argv));
  341. }
  342. else
  343. {
  344. NS_LOG_WARN ("Unsupported file format (only Maps/Weights are supported)");
  345. }
  346. regfree (&regex);
  347. }
  348. topgen.close ();
  349. NS_LOG_INFO ("Rocketfuel topology created with " << nodesNumber << " nodes and " << linksNumber << " links");
  350. return nodes;
  351. }
  352. } /* namespace ns3 */
  353. //-----------------------------------------------------------------------------
  354. // Unit tests
  355. //-----------------------------------------------------------------------------
  356. #include "ns3/log.h"
  357. #include "ns3/abort.h"
  358. #include "ns3/attribute.h"
  359. #include "ns3/object-factory.h"
  360. #include "ns3/object-factory.h"
  361. #include "ns3/simulator.h"
  362. #include "ns3/test.h"
  363. namespace ns3 {
  364. class RocketfuelTopologyReaderTest: public TestCase
  365. {
  366. public:
  367. RocketfuelTopologyReaderTest ();
  368. private:
  369. virtual bool DoRun (void);
  370. };
  371. RocketfuelTopologyReaderTest::RocketfuelTopologyReaderTest ()
  372. : TestCase ("RocketfuelTopologyReaderTest")
  373. {}
  374. bool
  375. RocketfuelTopologyReaderTest::DoRun (void)
  376. {
  377. Ptr<RocketfuelTopologyReader> inFile;
  378. NodeContainer nodes;
  379. std::string input ("./examples/topology-read/RocketFuel_toposample_1239_weights.txt");
  380. inFile = CreateObject<RocketfuelTopologyReader> ();
  381. inFile->SetFileName(input);
  382. if (inFile != 0)
  383. {
  384. nodes = inFile->Read ();
  385. }
  386. if (nodes.GetN () == 0)
  387. {
  388. NS_LOG_ERROR ("Problems reading node information the topology file. Failing.");
  389. return true;
  390. }
  391. if (inFile->LinksSize () == 0)
  392. {
  393. NS_LOG_ERROR ("Problems reading the topology file. Failing.");
  394. return true;
  395. }
  396. NS_LOG_INFO ("Rocketfuel topology created with " << nodes.GetN () << " nodes and " <<
  397. inFile->LinksSize () << " links (from " << input << ")");
  398. NS_TEST_EXPECT_MSG_EQ (nodes.GetN (),315, "noes");
  399. NS_TEST_EXPECT_MSG_EQ (inFile->LinksSize (),972, "links");
  400. Simulator::Destroy ();
  401. return false;
  402. }
  403. static class RocketfuelTopologyReaderTestSuite : public TestSuite
  404. {
  405. public:
  406. RocketfuelTopologyReaderTestSuite ();
  407. private:
  408. } g_rocketfueltopologyreaderTests;
  409. RocketfuelTopologyReaderTestSuite::RocketfuelTopologyReaderTestSuite ()
  410. : TestSuite ("rocketfuel-topology-reader", UNIT)
  411. {
  412. AddTestCase (new RocketfuelTopologyReaderTest ());
  413. }
  414. }