You are on page 1of 260

Institut fr Technische Informatik und Kommunikationsnetze

Evaluation of Scheduling Methods over Multipath Routing in Wireless Mobile Ad Hoc Networks
Semester Thesis, SA-2006-26 SS 06, April 2006 - July 2006

Authors:

Regula Gnner Dominik Schatzmann

Professor: Bernhard Plattner Advisor: Georgios Parissidis

Institut fr Technische Informatik und Kommunikationsnetze

Summer Semester 2006

Semester Thesis
for

Regula Gnner (D-ITET), Dominik Schatzmann (D-ITET)


Main Reader: Alternate Reader: Georgios Parissidis Martin May

Issue Date: 3. April 2006 Submission Date: 30. June 2006

Evaluation of scheduling methods over multipath routing in wireless mobile Ad Hoc networks

1 Introduction
Multi-path routing is not a new concept and has been proposed and implemented in packet and circuit switched networks. In circuit switched telephone networks alternate path routing was proposed in order to increase network utilization as well as to reduce the call blocking probability. However, the wide deployment of multi-path routing is so far prevented due to higher complexity and the additional cost of extra routes that need to be stored in the routers. Analysis and comparison of single path and multi-path routing with load balance mechanisms in ad hoc networks in terms of protocol overhead, traffic distribution and throughput has been conducted in [1]. The results reveal that in comparison with single-path routing, multi-path routing achieves higher throughput and increases network capacity. As the dimensions of mobile ad hoc networks are spatially bounded network congestion is inherently experienced in the center of the network as shortest paths mostly include nodes that are located at the center of the network. Thus a protocol in order to route data packets over non-congested links and maximize overall network throughput should target at utilizing the maximum available capacity of the calculated multiple routes. The authors concluded that routing or transport protocols in ad hoc networks should provide appropriate mechanisms to push the traffic further from the center of the network to less congested links. In [2] the effect of the number of multiple paths on routing performance has been studied using an analytical model. Their results showed that multi-path routing performs better than single path if the 1

number of alternative paths is limited to few paths. Simulation results of their model demonstrated that with multi-path routing end-to-end delay is higher as alternate paths tend to be longer. The goal of the present thesis is to conduct a performance evaluation of scheduling algorithms over multipath routing for mobile wireless Ad Hoc networks. Therefore, the main objectives of the present thesis are: 1. Implement and conduct a performance evaluation of scheduling algorithms (Round Robin, Weighted Round Robin, Proportional selection of paths) over a multipath routing protocol in mobile wireless Ad Hoc networks. 2. Propose and implement an optimized scheduling algorithm tailored for mobile wireless Ad Hoc networks that maximizes the throughput as well as minimizes the average end-to-end delay.

2 Conceptual Formulation
Wireless ad hoc networks consist of many features that differentiate them from conventional wired networks. The non-employment of multi-path routing in the standardized routing protocols used in the Internet today does not imply that multi-path routing is not an appropriate and promising solution for wireless mobile ad hoc networks. The unreliability of the wireless medium, the unpredictability of the network topology as node failures may occur frequently and the dynamic topology due to mobility of nodes result to frequent path breaks, network partitioning and high delays of path re-establishments. Multi-path routing represents a promising routing method for wireless mobile ad hoc networks. Multipath protocols establish multiple disjoint paths to the same destination. Thus, the probability of disconnection from the sender to the receiver is effectively reduced. Multi-path routing achieves load balancing of data traffic across network elements which is especially important in resource constrained environments, like mobile wireless ad hoc networks, where power is scarce and limited. Furthermore, multi-path routing attains more efficient protection to attacks. Spreading traffic over multiple paths, attacks such as packet interception and traffic analysis are much harder to perform. A multi-path routing protocol should fulfill the following properties: The routing protocol must provide multiple, loop-free and preferably node-disjoint paths to destinations. These two properties represent a strong measure of path independence. The multiple paths should be used simultaneously for data transport. Multiple routes need to be known at the source. A multi-path routing protocol for mobile ad hoc networks that satisfy the above-mentioned properties is the AOMDV [3]. AOMDV extends the AODV [4] to provide multiple paths. In AOMDV each RREQ and respectively RREP defines an alternative path to the source or destination. Multiple paths are maintained in routing entries in each node. The routing entries contain a list of next-hops along with corresponding hop counts for each destination To ensure loop-free paths AOMDV introduces the advertised_hop_count value at node i for destination d. This value represents the maximum hop-count for destination d available at node i. Consequently, alternate paths at node i for destination d are accepted only with lower hop-count than the advertised_hop_count value. An implementation of the AOMDV protocol in ns is available, however in the original implementation only one path is used at a time. Alternative paths are used as backup paths. Therefore, a modification of the original AOMDV source code should be done to implement the studied scheduling methods. Primarily, for the first part of the thesis we consider the following scheduling algorithms: 2

1. Round Robin: In this scheduling algorithm, a path is selected with the same probability among the multiple paths at the time a data packet is sent. Therefore, assuming that at time t, n paths are known at a sender s towards the destination d. A path i is selected with probability pi : pi = 1 , n
n

i=1

pi = 1, i [1, n].

(1)

2. Weighted Round Robin: The weighted Round Robin algorithm represents an special case of the Round Robin algorithm. On each path i a weight wi is assigned and accordingly a path is selected with probability pi :
n

pi = wi ,
i=1

wi = 1, i [1, n].

(2)

3. Proportional selection of paths: In this algorithm a proportion of available multiple paths is selected at each sender to disseminate data packets towards a destination. We assume two policies in the way paths are selected: a) N out of M. Select best N out of total M paths. b) Use only the best (N=1) out of M paths and keep the rest as backup. The optimal selection of paths on the "Proportional selection of paths" algorithm, as well as the optimal assignment of weights for the "Weighted Round Robin" algorithm depend on parameters that inherently influence the performance of each algorithm: Path duration/lifetime. The total time a path is active. Path length. The total number of hops between a source and a destination. Path breakage probability. The probability that a path will be active at the time a packet is scheduled to be sent. The second part of the thesis complements the performance evaluation of the studied scheduling algorithms. An optimized scheduling algorithm tailored for wireless mobile Ad Hoc that outperforms the abovementioned algorithms should be proposed and implemented.

2.1 Tasks
Summarizing, the essential tasks that need to be addressed in the present thesis are the following: 1. Performance evaluation of the abovementioned algorithms in the ns network simulator [5]. The performance evaluation should compare the different algorithms using the following metrics: a) Throughput: The ratio of the total number of packets delivered at the destination to the total number of data packets sent. b) Average end to end delay: The average end-to-end delay consists of propagation, queuing, retransmission at the MAC layer, and buffering delays for successfully delivered data packets. 2. Design and implementation of an optimized scheduling algorithm(s) over multiple paths for wireless mobile Ad Hoc networks that achieve higher throughput and lower end-to-end delay. A detailed timeline and a detailed list including a short description of each task is presented in table 1. Tasks are distributed evenly in two categories: A and B; one per student. Tasks 1. 2. 3. 4.
4.1 4.2 4.3 4.4

Time 1 week (3 April) 1 week (10 April) 1 week (17 April) 2 weeks (24 April)
24.04 - 01.05 24.04 - 01.05 01.05 - 08.05 01.05 - 08.05

5.
5.1 5.2

2 weeks (8 May)
08.05 - 22.05 08.05 - 22.05

6.
6.1 6.2 6.3

2 weeks (22 May)


22.05 - 05.06 22.05 - 05.06 22.05 - 05.06

7. 8. 9. 10.

1 week (05 June) 1 week (12 June) 2 weeks (19 June) 30 June

Task Description Related work Getting familiar with ns Installation/of a multipath routing protocol in ns Implementation of scheduling algorithms - Round Robin - Proportional selection of paths - Weighted Round Robin (incl. parameters) - Proportional selection of paths (incl. parameters) Performance evaluation of scheduling algorithms - RR + WRR - Prop. selection + Prop. selection (+ par.) Proposal of optimized scheduling algorithms - Based on 4.1, 4.2 - Based on 4.2, 4.3 - Intermediate Report Performance evaluation of proposed scheduling algorithms Assemble of the results Thesis report Submission of final thesis report Table 1: Timeline of the thesis

A * * * *

B * * *

* * * * * * * * * * * * * * * * *

3 Important remarks
1. A final timeplan for the realization of the semester thesis should be made by the end of the first week and discussed with the supervisor. 2. By the end of the second month a short intermediate report should be composed and reviewed during a meeting of the students with the supervisors. The intermediate report should list the already achieved tasks and the tasks that are foreseen to have been accomplished by the end of the thesis. Strictly speaking the intermediate report should comply with a structural design of the final report (in a bulleted form). 3. An ordinary contact (at least once a week) between the students and their supervisor has to take place via telephone, e-mail, meetings, tikiwiki semester thesis web page or other means. During 4

these contacts the progress of the performed work has to be shown and problems should be discussed. Especially important is the daily reading of e-mails.

4 Thesis Results
A fifteen minutes presentation should be given in TIK Institute. The exact date of the presentation will be specified late in the summer semester. Apart from this presentation, the following documents should be handed in: 1. A detailed technical report (Bericht) in English. The following topics should be thoroughly addressed in this report: a description of the investigated research area, a description of the examined scheduling algorithms, a listing of the solved and unsolved problems (together with the reasons why they havent been solved), references to literature, table of contents, figures,tables and potential appendices (glossary, programming code, etc.). The report should end up with an evaluation of how far the initial tasks of the thesis have been achieved and whether the initial timeplan was fulfilled. Five copies of the final report should be handed in, all bound and double sided printed. The technical report is preferred to be composed in Latex. 2. An abstract in both German and English, 1-2 pages long. This should contain a quick overview of the performed work. The structure of the abstract should be in the form: (1) Introduction, (2) Aims & Goals, (3) Results, (4) Future Work. 3. An electronic version of the technical report as well as of all the produced documents (code documentation, models etc.). Figures contained in the final report have to be additionally stored as independent data in a custom-selected format (ex. EPS). The material in electronic form should be either stored on a CD or in a separate directory on an institutes server (accounts should then be created for the students). 4. Referenced and processed literature, whether in electronic or printed form. 5. The complete source code of the system and of the test codes, together with all the necessary libraries/external programs.

References
[1] P. Pham and S. Perreau, Performance analysis of reactive shortest path and multi-path routing mechanism with load balance, INFOCOM, San Francisco, CA, USA, 2003. [2] A. Nasipuri, R. Castaneda, and S. R. Das, Performance of multipath routing for on-demand protocols in mobile ad hoc networks, Mob. Netw. Appl., vol. 6, no. 4, pp. 339349, 2001. [3] M. Marina and S. Das, On-demand multipath distance vector routing in ad hoc networks, Proceedings of the International Conference for Network Procotols (ICNP), November 2001. [4] C. E. Perkins, E. M. Belding-Royer, and S. Das, Ad hoc on-demand distance vector (aodv) routing, RFC 3561, July 2003. [5] ns-2: Network simulator, http://www.isi.edu/nsnam/ns/.

Abstract
In a wireless mobile ad hoc network multiple routes towards a destination can be established. Multipath routing protocols aims at achieving a higher throughput in the network. One method is to use the additional paths as back-up which can reduce the routing overhead and increase the performance [1]. With an enhanced selection of the paths (scheduling) the throughput of the network can be further increased. This thesis covers the design of a scheduling algorithm for the multipath routing protocol AOMDV. The first part of the work deals with the implementation of a general scheduling method e.g. round robin. The performance analysis of these schedulers, based on a scenario with random movement, did not show clear trends for further optimisation. For this reason the second part of the work uses a simplified, static scenario that consists of 61 nodes in a hexagonal structure and 19 additional nodes placed in a small area (node density hotspot scenario). The traffic is assumed to be uniformly distributed. Node density is used as scheduling metric. Based on this specific scenario the following points has been investigated. - Where is the bottleneck of the network and how is it related with the scheduling metric? - How many paths are known from the sender towards the destination. Is scheduling possible and efficient? - Which path can be found during the simulation? Do all paths go through the bottleneck? The investigation with the help of simulations showed that the bottleneck is not at the place with the highest node density. The number of paths that are available on average converges for longer paths (more than 3 hops) to one. Due to this result, scheduling for long paths is not possible. The paths, that are found for different route requests, differ in space. Due to the not sufficient number of paths for longer distances an alternative routing protocol should be used and the above mentioned questions should be answered for the new protocol.

ii

Zusammenfassung
In einem wireless mobile ad hoc Netzwerk knnen verschiedene Pfade fr eine Verbindung aufgebaut werden. Dies nutzen Multipath Routing Protokolle aus, um einen besseren Durchsatz des gesamten Netzwerkes zu erreichen. Eine Methode besteht darin die zustzlichen Pfade als Back-up zu verwenden. Dadurch wird der Routing Overhead verkleinert und der Durchsatz gesteigert [1]. Durch ein verbessertes Auswahlverfahren der Pfade (Scheduling) kann der Durchsatz des Netzwerkes weiter optimiert werden. Diese Arbeit setzt sich sich mit dem Entwurf eines Scheduling-Algorithmus fr das Multipath Routing Protokoll AOMDV auseinander. Der erste Teil der Arbeit befasst sich mit der Implementierung eines allgemeinen Scheduling-Verfahrens, mit dessen Hilfe verschiedene Scheduler wie z.B. Round Robin simuliert werden knnen. Die Performanceanalyse dieser Scheduler basierend auf einem Random Movement Scenario liefert jedoch keinen klaren Trends fr weitere Optimierung. Aus diesem Grund wird im zweiten Teil der Arbeit ein vereinfachtes statisches Scenario verwendet. Dieses besteht aus 61 Knoten die in einer sechseckigen Struktur angeordnet sind. Weitere 19 Knoten werden innerhalb einer kleinen Flche verteilt (Node Density Hotspot Scenario). Die Verbindungen werden als gleichverteilt angenommen. Als Scheduling Metrik wird Knotendichte (Node Density) verwendet. Anhand dieses spezifischen Szenarios werden folgende grundlegende Punkte untersucht: - Wo befindet sich die Schwachstelle (Bottleneck) des Netzwerk und wie hngt diese mit der Scheduling Metrik zusammen? - Wieviele Pfade kennt der Sender zum Ziel. Ist ein Scheduling mglich und effizient? - Welche Pfade werden whrend der Simulation gefunden? Verlaufen alle Pfade durch die gleiche Schwachstelle? Die Untersuchung mit Hilfe des Simulators zeigt, dass das Bottleneck nicht an der Stelle mit der hchsten Knotendichte auftritt. Die Anzahl Pfade, welche in der Quelle im Durchschnitt zur Verfgung stehen, konvergiert fr lnger Pfade (ab 3 Hops) gegen eins. Aus diesem Grund ist ein sinnvolles Scheduling fr lange Pfade nicht mglich. Fr verschiedene Route Requests werden meist solche Pfade gefunden, welche sich im Raum stark unterscheiden. Aufgrund der ungengenden Anzahl Pfade fr lngere Distanzen sollte ein anderes Routing Protokoll verwendet werden. Die oben erwhnten Punkte mssten fr dieses Protokoll erneut getestet werden.

iii

iv

Contents
1. Introduction 2. Theory 2.1. MANET . . . . 2.2. AODV . . . . . 2.3. AOMDV . . . 2.4. Related Work . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 1 3 3 3 4 4

3. Simulation Setup 3.1. Network Simulator . . . . . . . . . . . . . . . . . . . . . . . . . 3.1.1. Problems . . . . . . . . . . . . . . . . . . . . . . . . . . 3.1.1.1. ARP . . . . . . . . . . . . . . . . . . . . . . . 3.1.1.2. Packets Dropped due to Collision . . . . . . 3.1.2. Scheduling Functions . . . . . . . . . . . . . . . . . . . 3.1.3. Additional Packets . . . . . . . . . . . . . . . . . . . . 3.1.3.1. Ping Packet . . . . . . . . . . . . . . . . . . . 3.1.3.2. Info Packet . . . . . . . . . . . . . . . . . . . 3.1.4. Protocol Configuration, Selection of Parameters . . . 3.1.4.1. Transmission Range . . . . . . . . . . . . . . 3.2. Simulation Scripts . . . . . . . . . . . . . . . . . . . . . . . . . 3.2.1. Generate Scenario . . . . . . . . . . . . . . . . . . . . 3.2.2. Setting Up a Simulation . . . . . . . . . . . . . . . . . 3.2.2.1. Condor . . . . . . . . . . . . . . . . . . . . . 3.2.2.2. Create Files Required for Simulation . . . . 3.2.2.3. Script to Run Simulations on Remote Host 3.2.2.4. Parameters for ns2 . . . . . . . . . . . . . . 3.2.2.5. Start a Simulation . . . . . . . . . . . . . . . 3.2.3. Condense Information . . . . . . . . . . . . . . . . . . 3.2.3.1. Reduce Size of Output . . . . . . . . . . . . 3.2.3.2. Collect Data for Analysis . . . . . . . . . . . 4. Evaluation Tools 4.1. Evaluate One Simulation Run . . . . . . . . . . . 4.1.1. Temporal Behaviour of Number of Paths 4.1.2. Effectiveness of the Flooding . . . . . . . 4.1.3. Visualise Routing Table . . . . . . . . . . . 4.1.4. Area with High Rate of Dropped Packets 4.2. Evaluate Multiple Simulation Runs . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .

5 . 5 . 5 . 5 . 6 . 6 . 7 . 7 . 8 . 9 . 11 . 12 . 12 . 13 . 13 . 14 . 15 . 15 . 15 . 16 . 16 . 16 . . . . . . 17 17 18 18 19 20 20

Contents 5. Simulation Results 5.1. Validation of the Environment . . . . . . . . . . . . . 5.2. Static Hexagonal Scenario . . . . . . . . . . . . . . . 5.2.1. Number of Paths over Time . . . . . . . . . . 5.2.2. Number of Paths on Average . . . . . . . . . 5.2.3. Number of Dropped Packets Plotted as Area 5.2.4. Routing Table . . . . . . . . . . . . . . . . . . 5.2.4.1. Run Condition of AOMDV . . . . . 23 23 24 26 27 28 30 30

. . . . . . .

. . . . . . .

. . . . . . .

. . . . . . .

. . . . . . .

. . . . . . .

. . . . . . .

. . . . . . .

. . . . . . .

. . . . . . .

. . . . . . .

. . . . . . .

. . . . . . .

. . . . . . .

. . . . . . .

. . . . . . .

. . . . . . .

. . . . . . .

. . . . . . .

. . . . . . .

. . . . . . .

. . . . . . .

. . . . . . .

. . . . . . .

. . . . . . .

6. Further Work 33 6.1. AODV-Multipath . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 33 6.2. Improving AOMDV . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 33 7. Conclusion 35 7.1. Timeplan . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 35 7.2. Protocol . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 35 7.3. Goals Reached . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 35 A. Code A.1. C++ . A.1.1. A.1.2. A.1.3. A.1.4. A.1.5. A.2. Tcl . . A.2.1. A.3. Perl . A.3.1. A.3.2. A.3.3. A.3.4. A.3.5. A.3.6. A.4. Gawk A.4.1. A.4.2. . . . . . . . . . . . . . . . . . aodv.h . . . . . . . . . . . . aodv.cc . . . . . . . . . . . aodv_rtable.h . . . . . . . aodv_rtable.cc . . . . . . . aodv_packet.h . . . . . . . . . . . . . . . . . . . . . . . . aomdv.tcl . . . . . . . . . . . . . . . . . . . . . . . . . . . topology_generator.pl . . traffic_generator.pl . . . . create_simulation.pl . . . remote.pl . . . . . . . . . . analysis_one_run.pl . . . analysis_multiple_runs.pl . . . . . . . . . . . . . . . . . tr_to_val.awk . . . . . . . val_to_sim.awk . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 39 39 39 48 93 98 112 116 116 120 120 133 138 150 153 195 211 211 215

vi

List of Figures
3.1. 3.2. 3.3. 3.4. 3.5. 3.6. 4.1. 4.2. 4.3. 4.4. 4.5. 4.6. 5.1. 5.2. 5.3. 5.4. 5.5. 5.6. 5.7. 5.8. 5.9. Structure of the simulation environment . . . . . . . . . . . . . . . . . . . . . . . Concept of scheduling implementation . . . . . . . . . . . . . . . . . . . . . . . . Concept of the Ping message . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . Performance of a random movement scenario with and without Ping messages Concept of the Info packet . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . Topologies generated by topology_generator.pl , type 20, 30, 40 and 50 . . . . . . Structure of the simulation environment . . . . . . . . . . . . . . . . . Number of paths plotted over a time interval . . . . . . . . . . . . . . . Number of paths found on average partitioned by connection length Content of the routing tables . . . . . . . . . . . . . . . . . . . . . . . . Dropped Packets . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . Example of the output of analysis_multiple_runs.pl . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 5 6 7 8 8 12 17 18 18 19 20 22 23 24 24 26 27 28 29 30 31

Throughput of a random mobility, random placement scenario . . . . . Hexagonal hotspot scenario . . . . . . . . . . . . . . . . . . . . . . . . . . Throughput of a hexagonal hotspot scenario . . . . . . . . . . . . . . . . Number of paths for a time interval, 1 and 2 packets/s per connection . Number of paths ordered with shortest path length, 1 and 2 packets/sec Concept of the flooding mechanism . . . . . . . . . . . . . . . . . . . . . Dropped packets plotted in a 2D area, 1, 2, and 4 packets/sec . . . . . . . Content of the routing tables at a given time instant . . . . . . . . . . . Run condition in AOMDV . . . . . . . . . . . . . . . . . . . . . . . . . . . .

vii

viii

List of Tables
3.1. Example for selective Round Robin . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 7 3.2. Parameter configuration for validation simulations . . . . . . . . . . . . . . . . . . . . . . . . . 9 3.3. Configuration of the validation simulation . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 10 5.1. Parameter configuration for the simulation with hexagonal scenario . . . . . . . . . . . . . . . 25 5.2. Settings of the hexagon simulation . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 25

ix

List of Listings
3.3. 3.4. 3.5. 3.6. 4.1. 4.2. 4.3. 4.4. A.1. A.2. A.3. A.4. A.5. A.6. A.7. A.8. A.9. A.10. A.11. A.12. A.13. A.14. Parameters to configure ns2 simulation in aodv.h Using topology_generator.pl . . . . . . . . . . . . Using traffic_generator.pl . . . . . . . . . . . . . . Configure simulation parameters . . . . . . . . . Using analysis_one_run.pl . . . . . . . . . . . . . Use grep and ls for filtering . . . . . . . . . . . . . Filter of analysis_multiple_runs.pl . . . . . . . . . Selection of the axes . . . . . . . . . . . . . . . . . aodv.h . . . . . . . . . . . . . . . . . . . . . . . . . aodv.cc . . . . . . . . . . . . . . . . . . . . . . . . . aodv_rtable.h . . . . . . . . . . . . . . . . . . . . . aodv_rtable.cc . . . . . . . . . . . . . . . . . . . . aodv_packet.h . . . . . . . . . . . . . . . . . . . . aomdv.tcl . . . . . . . . . . . . . . . . . . . . . . . topology_generator.pl . . . . . . . . . . . . . . . . traffic_generator.pl . . . . . . . . . . . . . . . . . create_simulation.pl . . . . . . . . . . . . . . . . . remote.pl . . . . . . . . . . . . . . . . . . . . . . . analysis_one_run.pl . . . . . . . . . . . . . . . . . analysis_multiple_runs.pl . . . . . . . . . . . . . tr_to_val.awk . . . . . . . . . . . . . . . . . . . . . val_to_sim.awk . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 10 12 13 14 17 21 21 21 39 48 93 98 112 116 120 133 138 150 153 195 211 215

xi

xii

Abbreviations
AODV AODVM AOMDV ARP DSDV MAC MANET MSR NFS RERR RR RREP RREQ RTT WRR Ad hoc On demand Distance Vector Ad hoc On demand Distance Vector Multipath Ad hoc On demand Multipath Distance Vector Address Resolution Protocol Destination-Sequenced Distance-Vector Medium Access Control Mobile Ad Hoc Network Multipath Source Routing Network File System Route Error Round Robin Route Reply Route Request Round Trip Time Weighted Round Robin

xiii

xiv

1. Introduction
With the growing availability of wireless mobile devices, ad hoc networks are of increasing interest. Mobile ad hoc networks (MANET) consist of a collection of mobile wireless nodes and they transmit data without using fixed base stations or wired links. Typically the nodes have restricted processing power and memory resources. As the nodes have a limited communication range the path from source to destination has usually multiple hops and hence routing is crucial in MANETs. As wireless mobile networks have different characteristics from wired networks therefore special routing protocols have to be deployed. MANETs are more dynamic than wired networks and they do not have dedicated nodes for control. To optimal use network resources, the routing protocol has to react fast on events like a node joining or leaving the network in order to fix invalid paths or to find new paths. Due to the limited bandwith of the MANET the routing overhead and the probability of packet collisions should be minimised. In ad hoc networks often exist different paths from source to destination and the routing protocols can be divided into two different categories, those using only one path (singlepath routing) and those using multiple paths from source to destination (multipath protocols) [2]. Singlepath routing protocols can be divided into table-driven protocols and on demand routing protocols. The first establish and maintain routes to all available destinations while the latter set up a route if there is a demand for. The table-driven routing protocols detect routes in advance and maintain this information even if a route is not used. An example of such a routing protocol is the Destination Sequenced Distance Vector (DSDV) routing protocol that periodically transmits its entire routing table to all the neighbours or sends an update if a topology change has been detected. The drawback of this protocol in mobile environments is that these broadcasts introduce routing overhead that increases with frequent topology changes. Compared to table-driven protocols the routing overhead can be reduced if routes are only established if they are required (on demand protocols). An example of an on demand protocol is the Ad hoc On demand Distance Vector (AODV) routing protocol [3]. This protocol uses flooding to find a path from source to destination and in each hop is stored via which next hop a destination can be reached. Compared to tabledriven protocols the waiting time for the connection setup is larger as the protocol first has to find a route to the destination. Nodes in a MANET have limited transmission range and therefore a path from source to destination usually consists of multiple hops. As each link between those hops can break, the probability that a path breaks is higher the longer the path gets. The same holds for congestion and link quality. A singlepath routing protocol can reduce such effects only if it triggers new route searches, which increases the route overhead. Multipath routing protocols know multiple paths to the destination and can use them for load balancing or as a backup in case of a path break. Sending packets via different paths simultaneously can increase the reliability of the transmission as the effect of link failures is reduced but the receiver must be able to handle duplicate packets. The limitation of all the (multipath) protocols is given by the wireless medium. Even if multiple paths to a destination exist they can influence each other due to interference and will therefore not be totally independent. It was shown that on demand multipath routing protocols can outperform table-driven singlepath protocols [4] and that the performance depends on the used scheduling algorithm. Different solutions based on source routing were presented in [5]. Source routing generates more routing overhead than on demand protocols and is less suited for highly mobile nodes. This thesis uses Ad hoc On Demand Multipath Distance Vector an extension of the AODV protocol that 1

finds multiple paths to a destination and uses them as backup paths [1]. The AOMDV routing protocol has been extended with a set of scheduling functions to schedule over all paths and functions to evaluate the performance of the protocol. The performance of the scheduling methods is measured in terms of throughput and end-to-end delay and the evaluation is done using the network simulator ns2. In the following report we will give an introduction of MANETs and routing protocols and a survey on the related work. We will introduce the simulation environment and the scheduling methods together with all the scripts that have been developed to run simulations. Then all the evaluation tools and the performance evaluation will be presented. From these results conclusions will be drawn and different ideas for further work will be presented.

2. Theory
In the following part the concepts and backgrounds that are used for our work will be introduced. This consists of an introduction of mobile ad hoc networks, the routing protocol and the related work.

2.1. MANET
MANETs have four main issues to consider: Predictability of environment MANETs may be deployed in unknown terrain under hazardous conditions or in hostile environments and as a consequence node failures may be frequent. Unreliability of wireless medium Communication over a wireless medium is unreliable and error-prone and due to environmental conditions (interferences, weather) the quality of the link may be unpredictable. Resource restricted nodes may not be able to support transport protocols that ensure reliable communication. Resource-constrained nodes Mobile nodes are often restricted in computing power, memory and battery power and the algorithms have to be energy-efficient and should operate with low processing power. The limited energy can reduce the available bandwidth as the node may not have enough power to operate at full link speed. Dynamic topology As the nodes are mobile the topology of the network changes constantly. As a result in ad hoc networks different types of errors can occur: Transmission errors The unreliable wireless medium can destroy the transmitted packet [4]. Node failures Nodes may fail due to environmental conditions or they may drop out of the network voluntarily or due to lack of power. Link failures Node failures, movement or changed environmental conditions may cause link breakages. Route breakages Due to node or link failures the network topology changes and routes become outdated and thus incorrect and the routing protocol has to find a new route to the destination. Congested nodes or links Due to the topology of the network and the nature of the routing protocol, certain nodes or links may become overutilised. This will lead to either larger delays or packet loss.

2.2. AODV
To route packets in a mobile ad hoc network a specialised routing protocol is required. For single routing a widely used protocol is the Ad hoc On demand Distance Vector routing protocol [3]. AODV is a reactive routing protocol, which means that routes are only computed if they are required. If a source S wants to send data to destination D a route between these two nodes has to be found. For that purpose the source floods the network with RREQ packets (route request). Each node receiving the RREQ sends a route reply (RREP) if it knows a path to the destination (or it is the destination). If it does not know a path it rebroadcasts the request once. As soon as the source receives a RREP it can begin to transmit data. To determine the freshness of a route a destination sequence number is introduced, a larger sequence number indicates a newer route. All the nodes use received RREP and RREQ packets to update their routing tables if they contain newer information. If a node detects a broken link it sends a route error (RERR) packet as broadcast to all sources using this link. 3

2.3. AOMDV

2.3. AOMDV
If AODV is used and a path break occurs a new RREQ has to be sent. To reduce the routing overhead the multipath extension of AODV (AOMDV, Ad hoc On demand Multipath Distance Vector) [1] stores multiple paths to the destination and uses them as backup. As disjoint links break independently AOMDV establishes either link or node disjoint paths. To determine that a path is link disjoint each node forwarding a RREP has to check that the next and last hop of the path are unique. To get node disjoint paths the same check as with link disjoint paths is performed with the additional restriction that a node can only be part of one path. To prevent routing loops node do not accept routes that are longer than the already advertised and they do not advertise shorter routes than the advertised. If a node receives a route advertisement with a higher sequence number than the one it already has, it discards all the routes and updates with the new information.

2.4. Related Work


As a larger transmission radius interferes with more nodes the effective available bandwidth per node is reduced if the transmission radius is enlarged. It was shown that for this trade-off the optimal number of neighbours is (rounded) six. A scenario with the nodes distributed in hexagonal form is therefore ideal, as the number of neighbours is six for all the nodes except those at the border. The problem of optimal node density in a mobile ad hoc network is covered in [6]. The increase of the transmission range of a node decreases the available effective bandwidth seen at individual nodes, but it increases the connectivity of the network, an effect that may be more important as node mobility increases. The results do not show a global optimum number of neighbours for all mobility scenarios, but as mobility increases the optimum shifts to higher connectivity and therefore the node density should increase as the rate of node movements increases. [7] presents a load sensitive on demand routing approach that uses network load information to select paths. This routing method does not only include local load information but also the information about the load of all the neighbours. To obtain traffic information, the nodes continuously listen to neighbouring transmissions and hence the information can be gained without routing overhead. [8] presents a protocol to balance the traffic load over the network. The proposed scheme is intended to route data packets circumventing congested paths. This reduces the end-to-end delay and balances the load over the network. To find the path with least traffic a cost function is used that takes the activity of neighbours as a measure for traffic interference and sums this along the path. To gather information about the neighbours Hello packets are used. The information about the traffic is forwarded with the route setup message and the destination can then select the path with the minimal cost and as a consequence the traffic is evenly distributed over the network.

3. Simulation Setup
In the performance evaluation the network simulator ns2 version 2.26 has been used, as for this simulator already exists an implementation of the AOMDV protocol. In the following chapter the network simulator will be introduced, the scheduling functions will be described and the Info and Ping packets will be explained. The most important parameters to run the simulation are presented and a few important problems that have occurred are documented. To run the simulations more efficient Condor has been used and it will be explained below. In Fig. 3.1 the structure of the simulation environment can be seen, the explanation of the different parts will be splitted into two chapters.

Figure 3.1: Structure of the simulation environment

3.1. Network Simulator


ns2 is a discrete event network simulator for network research and it is running on UNIX-like operating systems [9]. The simulator consists of two parts: an object oriented simulator in C++ and an OTcl part to execute command scripts of the user. The C++ part is used for fast execution and therefore useful for running protocols. The OTcl part is used to configure the input via user scripts and it has the advantage that the entire system has not to be recompiled when an input has changed. In our simulation the Tcl script has been used to configure the simulation settings (such as nodes, traffic sources, channel type) and to start the simulation.

3.1.1. Problems
During the evolution of the thesis different problems have occurred. The two main problems concerning ns2 are described below. 3.1.1.1. ARP If a node wants to send data to a neighbouring node it first needs to know the MAC address of this node. This address can be found using the ARP protocol. The sending node will send an ARP request to find the MAC address of the neighbour. In ns2 there is a problem that if the ARP request is not answered by 5

3.1. Network Simulator

the neighbour (because it was not received, e.g. due to collision) then the message to this node can not be sent. ARP will not retry again and send a second request or report an error if the address can not be resolved. The consequence is that the pending message will stay in the ARP queue forever. As the ARP queue has the length of only one packet, the next time a packet has to be sent to this node, the old packet in the queue is dropped, the new packet is inserted in the queue and a new ARP request is sent. The packet is dropped with the message DROP_IFQ_ARP_FULL and in the trace file it is not obvious that this packet has been dropped due to a MAC address that was not resolved for long time. In extreme cases if only one packet is sent to a certain neighbour node and this ARP request can not be resolved, the message will be in the ARP queue until the end of the simulation and then it is dropped with the reason END. For the simulations a modified version of the ARP implementation has been used, setting #define arpOFFin the mac/arp.h file disables ARP. The simulations have been conducted without ARP. 3.1.1.2. Packets Dropped due to Collision If two packets are received at the same time, the MAC layer has to decide whether one of these packets can be decoded or not (see Sect. 3.1.4.1). If the packet with higher signal strength can not be decoded both packets are dropped. This event will not be written to the trace file with the argument that in reality the MAC layer would not have been able to decode this packet and gather information from it. This leads to the problem that the trace file can contain an entry that a certain packet has been sent or forwarded but this packet is never received. For evaluation purposes it would make sense that these packets are recorded as dropped with an error message that this occurred due to a collision with corrupt packets as consequence. With the current setup it is not possible to find out how many packets have been dropped due to a collision and corrupted packets as consequence. Only the collisions where one packet is received error free can be counted. As it can be of interest how much the MANET suffers from interferences the above mentioned configuration may be not useful.

3.1.2. Scheduling Functions


If a data packet has to be sent, the forward() function needs to find a path to the destination node. Therefore it calls path_find(destination, this_node). If the current node is the source of the packet, the scheduling function sched_get_path() is called. If the node is not the source, the first path in the route entry will be returned. The scheduling is implemented as shown in Fig. 3.2. Each available path is assigned a weight that is proportional to the probability that this specific path will be selected. The weights can be set according to different metrics and they define the type of the scheduling method. If all the weights are equal, the scheduling method is round robin. The weights are recalculated whenever a change in the routing table occurs

Figure 3.2: Concept of scheduling implementation

3.1. Network Simulator

and they are stored similar to a cumulative probability function. To select a path the sched_get_path() function will choose a random number and search through the weights array until the entry is larger than the random number. The corresponding path will then be returned to forward() (see Fig. 3.2). To change the behaviour of the scheduling method, the way the weights are assigned has to be changed. The sched_calc_weights() function contains a switch case to select the different schedulers. This selection is based on a variable that can be passed by the Tcl script. path weights 1 0 2 40 3 40 4 100 5 100

Table 3.1: Example for selective Round Robin In Tab. 3.1 an example of the weights array is given. The second path will be used with probability 0.4 and the fourth path with probability 0.6, the other three paths are not used. The probabilities depend on the selected metric, a simple round robin is implemented and depending on the path length a weighted and a selective weighted round robin is available. The weights are inversely proportional to the length of the path and for the selective WRR, path longer than 1.2 times the average are ignored. One scheduling configuration uses the round trip time (RTT) to select the weights of weighted round robin and one configuration is based on the total number of neighbours seen along the path (select the path with the lowest total number of neighbours). The last two methods depend on information about the path and therefore the weights have to be updated if new information is available. The information is provided using a Ping message that is sent along the path.

3.1.3. Additional Packets


3.1.3.1. Ping Packet To gather information of a specific route a Ping packet has been introduced. This packet is a special routing packet that is sent over all the available paths from the source to the destination and then returned to the sender. The packet is a routing packet to ensure that it is forwarded with priority in the queues. This is of importance if the round trip time (RTT) shall be measured, otherwise the length of the queue would be part of the round trip time, an effect that we wanted to avoid as we assume that the variance of the measurements would be higher in that case. The packet can measure the RTT of a path and it can collect information about the total number of neighbours along the route. It is extendable to measure other metrics.

Figure 3.3: Concept of the Ping message The Ping message is triggered by a timer as can be seen in Fig. 3.3. After the interval PING_INTERVAL a new Ping message is sent. If the next hop receives (recvPing ()), this message it checks whether it is the destination of the Ping message or not. If it is not, it will forward the Ping according to its own routing table. If the node is the destination it will call sendPong(), this function will create a new packet with 7

3.1. Network Simulator

the information to send the packet to the sender of the Ping message. The received packet will then be dropped. The Ping packet does not require large changes in the protocol, the packet structure has to be defined in aodv_packet.h, a new timer that invokes the sendPing () function has to be created and the functions to send and receive a Ping packet have to be provided. The interval to generate a packet can be defined, but the performance of the protocol using the Ping packet is much worse than without the Ping packet, which can be seen by comparing the two graphs in Fig. 3.4. In the simulation the Ping interval has been set to 4 seconds, depending on the packet rate this may be a significant part of the traffic and therefore the routing overhead is increased by this packet. Setting the interval is therefore a trade-off between performance and freshness of the information. As Ping messages shall only be sent along a used route, each node has to find out if it is the origin of a connection and the corresponding destination. This implies that each node has to store a list with the destination entries of its own connections, as only then a Ping shall be created. As our traffic generator assumes that only one connection can start from a specific node, we simplified the problem by creating a variable that will store the destination if the current node is the source. This does only work if the assumption, that each node can start one connection, is valid.

Delivery ratio versus load (random movement 1000 m x 1000 m) 1 delivery ratio [data pkt received / data pkt sent ] 0.9 0.8 0.7 0.6 0.5 0.4 0.3 0.2 1 2 3 4 packet rate [packets/s] (max con = 50; ps = 256; nn = 50; pt = 0; ms = 5.0) delivery ratio [data pkt received / data pkt sent ] 1 0.9 0.8 0.7 0.6 0.5 0.4 0.3 0.2 1

Delivery ratio versus load (random movement 1000 m x 1000 m)

AODV AOMDV RR WRR Sel

AODV AOMDV RR WRR Sel 2 3 4 packet rate [packets/s] (max con = 50; ps = 256; nn = 50; pt = 0; ms = 5.0)

Figure 3.4: Performance of a random movement scenario with and without Ping messages

3.1.3.2. Info Packet To have more information available for the analysis than the original trace file, an Info packet has been introduced. It can write path information to the trace file whenever a path change has occurred. If all information is written into one file the evaluation is simpler and therefore only one file has been used, even if this method is not very elegant. It would be possible to set a log target in the Tcl file and then use this file to store information. Printing all information into the same file has the advantage that the order of the events is preserved even if multiple events have the same timestamp due to the given resolution. The Info packet is a routing packet but it is never sent over the network, the packet is initialised and then dropped, the information will then be passed to the trace function and will be printed to the trace file.

Figure 3.5: Concept of the Info packet

The Info packet requires a function that can be called if a change in the routing table has occurred. This 8

3.1. Network Simulator

dumpPath(rt_entry, path, , #path) function takes the routing entry, the path and the number of paths as arguments together with the event that occurred (adding or removing a path). The function stores the information in a struct and calls sendInfo(). This is the function that uses the information out of the struct and creates an Info packet. This packet is then dropped. This event will invoke a trace function and a corresponding action (in trace/cmu-trace.cc) is executed in order to write the information to the trace file (see Lst. 3.1).
cas e AODVTYPE_INFO : / / dont use t h e o f f s e t t o o v e r w r i t e d e f a u l t p r i n t o u t s hd r _ ao d v _ i nf o i n f o ; i n f o = HDR_AODV_INFO( p ) ; s p r i n t f ( pt_ > b u f f e r ( ) , " i t %f Hs %d Hd %d I a %d I c %d " "I n %d I l %d I h %d I r %f " , Sched ul e r : : i n s t a n c e ( ) . c l o c k ( ) , i n f o >s r c , i n f o >dst , i n f o >act i o n , i n f o >path_count , i n f o >next_hop , i n f o >l as t _ ho p , i n f o >hop_count , i n f o > r t t ) ; / Hs S r c , Hd Dest , I a A c t i o n , I c Path Counter , I n Next Hop , I l L a s t Hop , I h Hop Count , I r RTT / b r eak ;

Listing 3.1: Handling of the Info packet in cmu-trace.cc

3.1.4. Protocol Configuration, Selection of Parameters


The simulations were performed using version 2.26 of the network simulator ns2 [9] with an extension of the AOMDV protocol from S. Das and M. Marina [10]. If not explicitly stated, default parameters of the simulator have been used. For the initial simulations and the validation of the system the following parameters have been chosen: dimensions number of nodes simulation time source type max number of connections packet size queue length 1km 1km 50 1000s CBR 30 256 50

Table 3.2: Parameter configuration for validation simulations

Phy / W i r el es s Phy Phy / W i r el es s Phy Phy / W i r el es s Phy Phy / W i r el es s Phy Phy / W i r el es s Phy Phy / W i r el es s Phy Mac/802 _ 1 1 Mac/802 _ 1 1

set set set set set set set set

CSThresh_ 3 .08319e11 RXThresh_ 1 .49226e10 bandwidth_ 2e6 Pt _ 0.1 freq_ 2 .472e9 L_ 1 .0 b a s i c R a t e _ 2e6 d at aR at e_ 54 e6

;# ;# ;# ;# ;# ;# ;# ;#

550m 250m outdated 1mW 2 .472GHz system l o s s 54Mps

Listing 3.2: Parameters to configure wireless behaviour

3.1. Network Simulator

The parameters in Tab. 3.3 are critical for simulations. Parameter Simulation area Node Density Node Coverage Footprint Maximum Path Network Diameter Neighbour Count Description area of topology node density in the sim. area area covered by a node transmission area covered by a node transmission in % max. distance of two nodes min. number of hops of the max. path Formula w h n w h r2 r2 w h 2 2 w + h 2 + h2 w r r2
wh n

Value 1km2 50/km2 0.19km2 19% 1.4km 6 hops 9.81

number of neighbour nodes (without edge effects) Table 3.3: Configuration of the validation simulation

# i f d e f AOMDV #d e f i n e AOMDV_PACKET_SALVAGING #d e f i n e AOMDV_MAX_SALVAGE_COUNT #e n d i f / / AOMDV #d e f i n e AODV_EXPANDING_RING_SEARCH / Allows l o c a l r e p a i r of routes / / /# d e f i n e AODV_LOCAL_REPAIR

10

/ A l l o w s AODV t o use l i n k l a y e r ( 8 0 2 . 1 1 ) f e e d b a c k i n d e t e r m i n i n g when l i n k s a r e up /down . / #d e f i n e AODV_LINK_LAYER_DETECTION #d e f i n e AODV_HELLO / / [ s c h e d u l i n g ] / / # d e f i n e AODV_PING #d e f i n e AODV_INFO / / # d e f i n e SA_DEBUG / / [ s c h e d u l i n g ] end / C a u s e s AODV t o a p p l y a " smoothing " f u n c t i o n t o t h e l i n k l a y e r f e e d b a c k t h a t i s ge n e r a t e d by 8 0 2 . 1 1 . I n e s s e n c e , i t r e q u i r e s t h a t RT_MAX_ERROR e r r o r s o c c u r s w i t h i n a window o f RT_MAX_ERROR_TIME b e f o r e t h e l i n k i s c o n s i d e r e d bad . / #d e f i n e AODV_USE_LL_METRIC / Only a p p l i e s i f AODV_USE_LL_METRIC i s d e f i n e d . C a u s e s AODV t o a p p l y o m n i s c i e n t knowledge t o t h e f e e d b a c k r e c e i v e d from 8 0 2 . 1 1 . T h i s may be flawed , b e c a u s e i t does not a c c o u n t f o r congestion . / / /# d e f i n e AODV_USE_GOD_FEEDBACK c l a s s AODV ; #d e f i n e MY_ROUTE_TIMEOUT 10 #d e f i n e ACTIVE_ROUTE_TIMEOUT 10 #d e f i n e REV_ROUTE_LIFE 6 #d e f i n e BCAST_ID_SAVE 6 / / [ s c h e d u l i n g ]

// // // //

10 s e c o n d s 10 s e c o n d s 6 seconds 6 seconds

10

3.1. Network Simulator

/ / we need a t i m e o u t f o r each path , s e t i t t h e same as t h e r o u t e t i m e o u t #d e f i n e ACTIVE_PATH_TIMEOUT 10 / / 10 s e c o n d s / / [ s c h e d u l i n g ] end / / No . o f t i m e s t o do networkwide s e a r c h b e f o r e t i m i n g out f o r / / MAX_RREQ_TIMEOUT s e c . #d e f i n e RREQ_RETRIES 3 / / t i m e o u t a f t e r doing networkwide s e a r c h RREQ_RETRIES t i m e s #d e f i n e MAX_RREQ_TIMEOUT 10.0 // sec / / S h o u l d be s e t by t h e u s e r u s i n g b e s t gu e s s ( c o n s e r v a t i v e ) #d e f i n e NETWORK_DIAMETER 30 / / 30 hops / V a r i o u s c o n s t a n t s used f o r t h e expanding r i n g s e a r c h / # i f d e f AODV_EXPANDING_RING_SEARCH #d e f i n e TTL_START 5 // 5 #d e f i n e TTL_INCREMENT 2 // 2 # e l s e / / NO EXPANDING RING SEARCH #d e f i n e TTL_START NETWORK_DIAMETER // 5 #d e f i n e TTL_INCREMENT NETWORK_DIAMETER // 2 #e n d i f / / NO EXPANDING RING SEARCH #d e f i n e TTL_THRESHOLD 7

/ / T h i s s h o u l d be somewhat r e l a t e d t o arp t i m e o u t #d e f i n e NODE_TRAVERSAL_TIME 0.03 / / 30 ms #d e f i n e LOCAL_REPAIR_WAIT_TIME 0 . 1 5 // sec / / Must be l a r g e r than t h e time d i f f e r e n c e between a node p r o p a ga t e s a r o u t e / / r e q u e s t and g e t s t h e r o u t e r e p l y back . #d e f i n e RREP_WAIT_TIME #d e f i n e ID_NOT_FOUND #d e f i n e ID_FOUND 1.0 0x00 0x01 // sec

/ / The f o l l o w i n g s a r e used f o r t h e f o r w a r d ( ) f u n c t i o n . C o n t r o l s p a c i n g . #d e f i n e DELAY 1.0 / / random d e l a y #d e f i n e NO_DELAY 1.0 / / no d e l a y / / t h i n k i t s h o u l d be 30 ms #d e f i n e ARP_DELAY 0.01 #d e f i n e #d e f i n e #d e f i n e #d e f i n e #d e f i n e HELLO_INTERVAL ALLOWED_HELLO_LOSS BAD_LINK_LIFETIME MaxHelloInterval MinHelloInterval / / f i x e d d e l a y t o keep arp happy

1 / / 1000 ms 3 // packets 3 / / 3000 ms ( 1 . 2 5 HELLO_INTERVAL ) ( 0 . 7 5 HELLO_INTERVAL ) 4 // 4s

/ / [ s c h e d u l i n g ] #d e f i n e PING_INTERVAL / / [ s c h e d u l i n g ] end

Listing 3.3: Parameters to configure ns2 simulation in aodv.h 3.1.4.1. Transmission Range In ns2 exist three different parameters to define the transmission and interference range of a node. The node transmits with a certain amount of power that can be define in Pt. This power is reduced with the distance according to the selected propagation model (FreeSpace, TwoRayGround, Shadowing). If a receiving node receives a signal with a field strength above the threshold RXThresh the packet can be decoded error free. If two packets arrive at the same time the ratio of their respective field strengths has to be larger than CPThresh (in dB), then the packet with higher field strength can be received error free. Otherwise both packets are dropped. If a node detects a signal above the threshold CSThresh it can not decode the packet but it can find out that the medium is not free. Therefore this determines the carrier sense range. If a 11

3.2. Simulation Scripts

node wants to transmit it has first to check whether it can detect a field strength that is above CSThresh and only if this is not the case it is allowed to transmit. The two thresholds RXThresh and CSThresh can be seen as radii around the node, the first indicates the range a node can successfully send its packets and the second the range a node can detect other transmissions. If the MAC layer decides that a packet is received (according to the thresholds) this packet is always received correctly as the channel does not introduce any bit errors.

3.2. Simulation Scripts


3.2.1. Generate Scenario
To create different topologies a generator (topology_generator.pl) has been developed. It can either call the generator of ns2 (setdest) or it can build new topologies. Four types can be generated: regular hexagon, 61 nodes regular hexagon, additional 19 nodes placed uniformly regular hexagon, additional 19 nodes in a small area (hotspot) circle with uniformly placed nodes, total 80 nodes The regular scenarios use a distance of 175 m between nodes and it is possible to add jitter to their position. The number of nodes, the jitter and the distance can be changed, as they are variables in the script. The topology generator can be started by entering the following command with proper command line options as seen in Lst. 3.4. The type defines the type of the topology and can be specified by a number, in Fig. 3.6 examples for type 20, 30 40 and 50 can be seen.

Figure 3.6: Topologies generated by topology_generator.pl , type 20, 30, 40 and 50


p er l topology_generator . pl use : nn [ num_of_nodes ] pause [ pausetime ] speed [ maxspeed ] simtime [ simtime ] x [ maxx ] y [ maxy ] t y p e [ t y p e o f scen ] seed [ random seed ] > [ o u t d i r /movement f i l e ]

Listing 3.4: Using topology_generator.pl To distribute the traffic uniformly a traffic generator has been created (traffic_generator.pl). It can be used as seen in Lst. 3.5. Even if the traffic type has to be given, only cbr is implemented, tcp will return an error.

12

3.2. Simulation Scripts

perl traffic_generator . pl use : t y p e [ cb r | t cp ] nn [ number o f nodes ] seed [ random seed ] nc [ number o f co nnect i o ns ] r a t e [ p acket / s ] p k t s i z e [ p acket s i z e ]

Listing 3.5: Using traffic_generator.pl The source and destination are chosen randomly with the restriction that a specific node is not allowed to have more than a maximum number of connections. In the script, the number of how many connections maximally can start and end in each node can be defined. For both generators a random seed can be set to be able to reproduce the state.

3.2.2. Setting Up a Simulation


As the simulation environment has many free parameters a large amount of calculation power is required to find optimal results. As the simulations are independent of each other they can be run simultaneously on different machines. To have more CPU power available Condor [11] has been used. Condor is a system that manages and distributes jobs on different machines if they have free CPU resources. To simplify the start of a simulation different scripts have been developed. 3.2.2.1. Condor Condor [12] is a scheduler that runs jobs on idle workstations. On the computer infrastructure of the EE department the Condor server is installed and all machines hosted by the ISG.EE such as tardis-d01 and tik43x are part of the cluster. A Condor job is defined by an executable file (which is the same for all jobs). The job is started on an idle workstation. If anybody logs on this machine the job is set into sleep mode. If the user is active longer than a certain time the sleeping task is killed. All information is lost and the job has to be restarted on an other machine. Consequential the jobs should have a runtime shorter than one hour to increase the chance that they are not interrupted. As each job runs on a different host the network file system (NFS) is used to give the jobs access to the home directory. Each job will store its output in this directory and depending on the number of jobs and the size of the output per job, enough disk space is required. To submit the jobs to Condor a file (run_simulation.condor) containing a list with all jobs is used and the following command will submit the jobs to the cluster.
schadomi@tardisa03 :~ > condor_submit r u n _ s i m u l a t i o n . condor

The Condor file is constructed by the create_simulation.pl script and contains all jobs and system parameters for a Condor session. The executable file is the remote.pl. Each job has the rights of the user that submitted the job. The effect is, that as a student with normal ITET rights, the Condor jobs can only be executed on the workstation of the ISG student rooms. To access the computers of the TIK as student some changes in the submit file have to be done. With the command
+USER_GROUP +JOB_GROUP = " tik " = " tik "

in the Condor file the rights management of Condor is overwritten and the jobs run on machines of the TIK institute and the ISG workstations. By default for each completed job an email is sent. To avoid this
Notification = Error

should be placed in the Condor file, as then only in the case of an error a notification is sent. The progress and error messages can nevertheless be found in the log folder. By defining requirements on the infrastructure specific clients from the cluster can be selected. As the simulation runs only on Linux the following configuration has been used.

13

3.2. Simulation Scripts

Requirements = ( ( || || || || && &&

Arch == " INTEL " Arch == " PPC " Arch == " x86_64 " Arch == " ALPHA " Arch == " SUN4u" ) ( OpSys == " LINUX " ) Memory >=32 )

3.2.2.2. Create Files Required for Simulation To create a package with all the files required to start a simulation with Condor the create_simulation.pl script has been developed. The script can be configured by specifying the parameters as in Lst. 3.6.
# # General my $n_of_run # Variables my @queue_type my @queue_length my @dim_x my @dim_y my @n_node my @sim_time my @sim_progress # Moving p a t t e r n my @pause_time my @max_speed my @scen_type # T r a f f i c pattern my @source_type my @num_connect my @p acket _ s i z e my @packet_rate # AOMDV parameter my @sched_type = 5; ## number o f s i m u l a t i o n s

= = = = =

( Queue / D r o p T a i l / PriQueue ) ; ## i n t e r f a c e queue t y p e (50); ## l e n g t h o f i n t e r f a c e queue ( i n p a c k e t s ) (2000); ## x ( network dim ) > 2000 f o r s c e n e != 00 (2000); ## y ( network dim ) > 2000 f o r s c e n e != 00 (80); ## number o f nodes > 80 f o r s c e n e != 00 ## s i m u l a t i o n d u r a t i o n ## s i m u l a t i o n p r o g r e s s , not used

= (1000); = (100);

= (0); = ( 0.0 ) ; = ( 40 ) ;

## pause time ( pause between moving ) ## max s p e e d [m/ s ] ## s e e t o p o l o g y _ g e n e r a t o r . p l f o r h e l p

= ( cb r ) ; = (50); = (256);

## t y p e o f t r a f f i c s o u r c e ( " c b r " o r " t c p " ) ## number o f c o n n e c t i o n s ## p a c k e t s i z e [ B y t e s ] ## p a c k e t r a t e [ p a c k e t / s e c o n d ]

= ( 1 . 0 , 1 . 5 , 2.0 ) ;

= ( 0 , 1 , 2 , 3 ) ; ## ## ## ## ## ## ## 0 = 1 = 2 = 3 = 4 = 5 = max

## t y p e o f path s c h e d u l e r S e l e c t o n l y one [ aomdv ] ( s h o r t e s t path ) Round Robin [ RR ] Weighted RR [WRR] ( 1 / hop ) S e l e c t i v e WRR [ SWRR ] WRR RTT ( needs p i n g ) Neighbour ( needs p i n g ) o f p a t h s between s o u r c e and d e s t i n a t i o n

my @max_path

= (1);

Listing 3.6: Configure simulation parameters

According to these parameters the traffic and topology patterns are created (traffic_generator.pl, topology_generator.pl). Those patterns are stored in the pattern folder and they are only generated if they do not yet exist. The script also creates the Condor file that is used to sumbit the jobs. Before a job is added to the list, it is checked if the point has already been simulated (simulated results can be found in the sim_data folder). With all the required files a tar archive is created and copied to a remote machine. 14

3.2. Simulation Scripts

3.2.2.3. Script to Run Simulations on Remote Host To start the simulation the remote.pl script is used. This script takes command line arguments that are then passed via command line to the Tcl script that actually starts the simulation. The script sets the paths to the Tcl libraries and waits until the .sim file has a nonzero filesize or a timeout occurs. This check has to be done as different processes are started by the script and it they have to be finished before the script terminates, otherwise the simulation results get lost. Even if the ns2 executable is compiled using static flags the Tcl libraries are installed on one of the remote hosts (and then accessible via NFS) to avoid conflicts. The source to install the libraries can be found in source/ns-small-2.26.tar.gz 3.2.2.4. Parameters for ns2 The aomdv.tcl scripts is the interface to the simulation environment. This script is used to set all parameters of ns2 and to start the simulation. In Lst. 3.7 the parameters of the Tcl file can be seen.
set set set set set set set set set set set set tracefile_ mobility_pattern_ traffic_pattern_ queue_type_ queue_length_ dimension_x_ dimension_y_ number_of_node_ sim_time_ s i m _ p r o g r es s _ s ched _ t y p e_ i n_ aomdv_max_path_in_ [ lindex [ lindex [ lindex [ lindex [ lindex [ lindex [ lindex [ lindex [ lindex [ lindex [ lindex [ lindex $ ar g v 0 ] ; $ ar g v 1]; $ ar g v 2 ] ; $ ar g v 3 ] ; $ ar g v 4 ] ; $ ar g v 5 ] ; $ ar g v 6 ] ; $ ar g v 7 ] ; $ ar g v 8 ] ; $ ar g v 9 ] ; $ ar g v 1 0 ] ; $ ar g v 1 1 ] ; # # # # # # # # # # # # tracefile mobility pattern t r a f f i c pattern [ CMUPriQueue Queue / D r o p T a i l / P r i Q u e u e ] Queue l eng t h max p a c k e t l eng t h i n i f q Dimension X Dimension Y Simulation duration S i m u l a t i o n p r o g e s s = pause_time ? t y p e o f AOMDV s c h e d u l e r maximum number o f p a t h s

Listing 3.7: Parameters in the aomdv.tcl file To evaluate the simulation all the actions of the routing and data packets are written into a trace file. The file is opened in this script and the filehandler is passed to the C functions. The problem with this setup is, that Tcl does not allow files larger than 2GB. This file size is reached if the number of nodes is high or if a lot of route requests (flooding) are sent. For a simulation with 100 nodes the 2GB are reached after a simulation time of about 500 seconds. The script then reports an error and does not write any more data to the file. To circumvent this problem we decided not to write the data to a file but to parse it on the fly. This can be done by piping the output to the used gawk scripts. This solution requires more RAM than writing the data to a file but this has not been a problem with our simulations.
s e t t r a c e f d [ open " | gawk f t r _ t o _ v a l . a w k | \ gawk v M_N = $number_of_node_ f v al _ t o _ s i m . aw k > $ t r a c e f i l e _ . s i m " w]

3.2.2.5. Start a Simulation To start a simulation follow the following steps. 1. Installation: Install the Tcl libraries in the ITET NFS space Adjust library paths in remote.pl 2. Edit create_simulation.pl Adjust system environment parameters as path to ns2 , username Adjust simulation version and testseries tags. perl create_simulation . pl

Adjust simulation parameters such as number of nodes, packet rate

3. Start condor 15

3.2. Simulation Scripts

Log in on an ISG machine

Change to the packet folder, e.g. cd /home/schadomi/extra/V001-001 Submit condor job list by condor_submit run_simulation.condor wait until all simulation are finished 4. Collect results

extract archive into the local sim_data folder

copy the archive to the localhost with scp

tar the simulation results of the sim_data folder with tar czvf sim_data_XXX.tar.gz sim_data

3.2.3. Condense Information


3.2.3.1. Reduce Size of Output The tr_to_val.awk is used to save the information of the trace file in a more compact form. This is achieved by removing unnecessary information. The script has been developed by Rainer Baumann and was modified to support Ping and Info packets. During our simulation a bug in tr_to_val.awk was found if a node with IP address zero is used. In reality this zero is not used for nodes (broadcast) but in the simulation this can be the case. If the topology generator of ns2 is used, the input of 50 nodes returns nodes with ids from 0 to 49. The problem is that the topology generator begins to number the nodes with zero. As consequence the node with id zero will be created. This bug has been fixed. 3.2.3.2. Collect Data for Analysis The val_to_sim.awk script uses the output of the tr_to_val.awk script as input to collect the needed information for the analysis and stores it in a .sim file. These files have unique file names based on the simulation parameters. The script is based on an existing script that collects data for each node. In the first 180 seconds of the simulation all connections are set up and it is assumed (without proof) that after this time the network is in steady state. As the start up time should not be taken into account, only packets that arrive after the first 180 seconds are counted. The val_to_sim.awk scripts consists of different parts, one for the initialisation, one to handle the different events and the last is performed at the end. Five different events are distinguished. Either a packet is sent, forwarded, dropped or received or an Info packet has been printed to the trace file. All these events will trigger different actions, if a packet has been handled, different counters are incremented, the Info packet will be parsed and the information is stored in different tables. Handling an Info packet is quite different to the other events and therefore it will be explained in more detail. In a first step the routing tables of all nodes are rebuilt or updated using the information of the Info packet and these tables are stored in one large table. If a change in the routing table of a sending node occurs all the paths from this source to the destination are reconstructed. As all the information of the nodes routing tables is available a recursive function searches through these tables and constructs all possible paths to the destination without a check for disjointness. The found paths represent the state of the routing tables at this time instance. Packets are forwarded by looking up the routing entry for the corresponding destination and therefore all the paths that the protocol may use can be found with the recursive function. The result of this recursive search is stored in a table together with the information at which time this path has been existing in the network. These information can be used to reconstruct the routing tables at any given time instance. To count the number of disjoint paths from source to destination other information is required. The reconstructed paths are not disjoint but in the Info packet the number of disjoint paths for each connection is indicated (as the source only knows about disjoint paths). This values are used for the statistics of the number of available paths.

16

4. Evaluation Tools
To show the behaviour of the network, different evaluation tools have been developed. Either one specific simulation run can be investigated in detail or statistics over multiple runs can be created. These tools generate graphical output to visualise the results. As we used a special scenario (hexagon with hotspot) a topology generator was created and to distribute the traffic uniformly on the nodes a traffic generator had to be developed.

Figure 4.1: Structure of the simulation environment

4.1. Evaluate One Simulation Run


To evaluate different aspects of the protocol, one specific run can be investigated. For scheduling the number of paths available at a given time instance as well as average over the simulation is of interst. To determine whether the implementation is correct the content of the routing table is used to reconstruct all possible paths and to identify the bottleneck of the simulation the dropped packets are plotted over the simulated area. All these evaluations are done for one specific simulation and are implemented in the perl script analysis_one_run.pl. The script reads the data from the .sim file that is passed as command line argument (see Lst. 4.1) and calculates all the required values in advance, then a menu is displayed to select different functions.
p er l analysis_one_run . pl use : f i l e [ SIM F I L E ]

Listing 4.1: Using analysis_one_run.pl

17

4.1. Evaluate One Simulation Run

4.1.1. Temporal Behaviour of Number of Paths


The number of available paths at a given time instance is very interesting for the scheduling. As in Fig. 4.1.1 the number of available paths for one connection can be plotted. The script also calculates the average number of paths for this connection over the entire simulation time. If no paths are available the routing protocol will generate a RREQ to find a route to the destination.
Number of paths on average over time 2.5 # paths # paths time avg 2 number of paths

1.5

0.5

0 300

310

320 time [s]

330

340

350

Figure 4.2: Number of paths plotted over a time interval

4.1.2. Effectiveness of the Flooding


Averaging the average number of available paths over all the connections with the same length (length of shortest path) is plotted in Fig. 4.3. To see the performance of the flooding the average number of paths found by a route request can be plotted. A route request is sent if no path is available therefore the route requests can be identified by the zero periods as seen in Fig. 4.1.1. The maximal value between two zero events is the maximal number of paths found by a route request. The number of connection is also plotted as this is a measure of how many samples are available. To show the accuracy of the average values the standard deviation is plotted.
Paths found on average for a shortest path with x hops (t>180) 7 20 paths avg on time paths after one RREQ 6 # connections number of paths 5 4 10 3 2 1 0 1 2 3 4 hops 5 6 7 0 number of connections 15

Figure 4.3: Number of paths found on average partitioned by connection length

18

4.1. Evaluate One Simulation Run

4.1.3. Visualise Routing Table


The Info packets contain all the information that is required to reconstruct the routing table at any given time instance. These information is collected by the script val_to_sim.awk and the routing table is created. In theory the protocol claims that it finds node or link disjoint paths. But by rebuilding the routing table it can be shown that non-disjoint paths can be created. Each node knows the path to a destination together with the next and last hop. At a forwarding node the last hop of the selected path is not taken into account and therefore the paths can not be guaranteed to be disjoint. In the routing table leftovers from the flooding can be found, as reverse paths are inserted in the table and will expire after a certain time; see Sect. 5.2.4.1. The analysis_one_run.pl script can draw the state of the routing table at a given time instance. It can create snapshots of these states and build an animated gif with correct timing between the snapshots. To create the animated gif a small program named whirlgif [13] has been used.

Content of routing tables 1500 0.025 0.02 0.015 1000 Y Y 0.01 0.005 0 500

0 0 500 X
Figure 4.4: Content of the routing tables

1000

1500

19

4.2. Evaluate Multiple Simulation Runs

4.1.4. Area with High Rate of Dropped Packets


The script analysis_one_run.pl can create a plot of the nodes and draw the relative amount of dropped packets. Gnuplot has been used to plot the area and interpolate the values between the nodes. To be able to use this script information about the ratio of dropped packets is required which is calculated in val_to_sim.awk. Drawing the dropped packet depending on the position if the node makes only sense if the scenario is static. For a mobile scenario a solution could be to record the coordinates of each dropped packet and to create then a map out of this data. But as the tool has only been used for static scenarios the packets are assigned to a node and not a position. Figure 4.5 shows an example of the dropped packets plotted over the simulated area.

Dropped data packets over total sent data packets 1500 0.01 0.008 0.006 1000 Y 0.004 0.002 0 500

0 0 500 X
Figure 4.5: Dropped Packets

1000

1500

4.2. Evaluate Multiple Simulation Runs


The evaluation of multiple simulation files is done with the scripts analysis_multiple_runs.pl. The script expects that all the files to evaluate are stored in one folder. The script then uses a filtering function (based on ls and grep, see Lst. 4.2) to find the files that are part of the analysis. The filter is based on the fact that all the information to identify a simulation is part of the filename. Listing 4.3 shows how to set the filter parameters.

20

4.2. Evaluate Multiple Simulation Runs

f o r ( $x_dim_index= 0 ; $x_dim_index < s c a l a r ( @x_dim_grep ) ; $x_dim_index ++)

Listing 4.2: Use grep and ls for filtering


# s e t f i x parameters # # V e r s i o n eg V002 # number_of_run # queue_type # q u e u e _ l e n gt h # dimension_x # dimension_y # simulation_duration # sim_progress # source_type # ending my my my my my my my $queue_type $queue_length $dimension_x $dimension_y $ s i m _ d ur at i o n $ s i m _ p r o g r es s $source_type

=" V001 . " =" r i . " ; =" qt 0 ."; =" q l 50 ."; =" dx 1500 ."; =" dy 1500 ."; =" sd 1000 ."; =" sp 10 ."; =" s t . c b r . " ; =" sim " ; = = = = = = = 0; 50; 2000; 2000; 1000; 100; cb r ;

e l s i f ( $ c h o i c e _ f i x eq " hexa ho t s p o t " ) { # s c e n a r i o 40 $dimension_x $dimension_y = 2000; = 2000;

$fix_grep = " $version " . " . r i " . " . qt$queue_type " . " . ql$queue_length " . " .dx$dimension_x " . " .dy$dimension_y " . " . sd$ s i m _ d ur at i o n " . " . sp$ s i m _ p r o g r es s " . " . scp 40" . " . s t . $ s o u r c e _ t y p e " . " . $simulation_result_type " ; $ f i x _ t i t l e = " hexagon ho t s p o t $dimension_x m x $dimension_y m" ; $ f i x _ f i l e _ n a m e = " [ $ v e r s i o ndx$dimension_x dy$dimension_yhexaho t s p o t ] " ; }

Listing 4.3: Filter of analysis_multiple_runs.pl To select the values that are plotted, in Lst. 4.4 for each axis the properties can be set (the z-dimension are the protocol/scheduler configurations). The configuration of the example will result in a plot of the load of AODV, AOMDV, RR, WRR and selective WRR versus the delivery ratio.
$choice_z #$ch o i ce_z $choice_x #$ c h o i c e _ x #$ c h o i c e _ x #$ c h o i c e _ x #$ c h o i c e _ x $choice_y #$ c h o i c e _ y = o nl y 4 ; = all ; = = = = = l o ad ; load_fine ; node d e n s i t y ; movement pause time ; movement s p e e d ;

= ratio ; = delay ;

Listing 4.4: Selection of the axes

21

4.2. Evaluate Multiple Simulation Runs

The output of the analysis_multiple_runs.pl script is an .eps file that is stored in the temp folder. In Fig. 4.6 an example of the output of the analysis_multiple_runs.pl script can be seen.
Delivery ratio versus load (hexagon hotspot 2000 m x 2000 m) 1 delivery ratio [data pkt received / data pkt sent ]

0.9

0.8

0.7

0.6 AODV AOMDV RR WRR Sel 1 2 3 4 packet rate [packets/s] (max con = 50; ps = 256; nn = 80; pt = 0; ms = 0.0)

0.5

0.4

Figure 4.6: Example of the output of analysis_multiple_runs.pl

22

5. Simulation Results
5.1. Validation of the Environment
To ensure that the simulation environment behaves as expected, different simulations have been conducted. It can be seen that the AOMDV protocol using multiple paths has the same or better performance as the AOMDV with only one path (AOMDV as singlepath is similar to AODV), a result that has been expected. The different scheduling algorithms that have been implemented do not show a general trend, on average they have the same performance as the AOMDV with multiple paths. All the simulations have been conducted using node disjoint paths even if there exist more link disjoint than node disjoint paths. Using link disjoint paths is problematic as the implementation of the protocol can not determine which input path corresponds to which output if a node is part of multiple link disjoint paths. If the scheduling uses information about a specific path it is necessary that the packet is sent via this defined path, but the protocol can not guarantee this. To avoid this problem node disjoint paths have been used.
Delivery ratio versus load (random movement 1000 m x 1000 m) 1 delivery ratio [data pkt received / data pkt sent ]

0.9

0.8

0.7

0.6 AODV AOMDV RR WRR Sel 1 2 3 4 5 packet rate [packets/s] (max con = 30; ps = 256; nn = 50; pt = 0; ms = 5.0)

0.5

0.4

Figure 5.1: Throughput of a random mobility, random placement scenario

23

5.2. Static Hexagonal Scenario

5.2. Static Hexagonal Scenario


As the results from the validation did not show large differences for the different schedulers, we decided to create a smaller problem where a certain question can be investigated. The problem was based on a static scenario and uniformly distributed traffic. The question was if it would be possible to increase the performance of a hospot scenario (certain area with high node density) by using the node density as a scheduling metric. To answer this question a hexagon with equidistant nodes has been chosen and some nodes have been placed randomly in a small area to create a hotspot (for the topology generator refer to Sect. 3.2.1). To investigate this problem it has been splitted into different subproblems. As the throughput shall be increased first the bottleneck of the scenario has to be identified. Then the question is if enough paths can be found to allow scheduling. The last question is if always the same paths are found and where in the scenario they are located. As the throughput should be increased the paths have to allow a routing around the bottleneck. In Fig. 5.2 one realisation of a hexagonal hotspot scenario can be seen.

Figure 5.2: Hexagonal hotspot scenario Figure 5.3 shows the throughput of a hexagonal hotspot scenario. It can be seen that the different scheduling methods do not increase the performance. As expected the throughput of the multipath configuration is higher than with the singlepath configuration.
Delivery ratio versus load (hexagon hotspot 2000 m x 2000 m) 1 delivery ratio [data pkt received / data pkt sent ]

0.9

0.8

0.7

0.6 AODV AOMDV RR WRR Sel 1 2 3 4

0.5

0.4 packet rate [packets/s] (max con = 50; ps = 256; nn = 80; pt = 0; ms = 0.0)

Figure 5.3: Throughput of a hexagonal hotspot scenario

24

5.2. Static Hexagonal Scenario

The following configuration has been used for the simulations to answer these questions: dimensions number of nodes simulation time source type max number of connections packet size queue length 2km 2km 80 1000s CBR 50 256 50

Table 5.1: Parameter configuration for the simulation with hexagonal scenario

The following parameters are critical for simulations: Parameter Simulation area Node Density Node Coverage Footprint Maximum Path Network Diameter Neighbour Count Description area of hexagon node density area covered by a node transmission area covered by a node transmission in % max. distance in hexagon max. shortest path through hexagon number of neighbour nodes Table 5.2: Settings of the hexagon simulation Value 1,98 km2 40/km2 0.19km2 9,6% 1.75km 10 hops >6

25

5.2. Static Hexagonal Scenario

5.2.1. Number of Paths over Time


The number of paths that are available at a given time instance can be plotted using analysis_one_run.pl (see Sect. 4.1.1). For the hexagonal hotspot scenario the results are given in Fig. 5.4 for two different loads. If no path is available a route request is sent and the found paths are inserted. In Fig. 5.4 the same time interval and the same connection is plotted, only the packet rate is changed. In both plots periods without available paths can be observed. As the scenario is static, paths can not get lost due to mobility. The paths are lost as link layer detection is used. This means that the link layer will try to send a packet during a given interval. If it is not able to transmit the packet within this time, it assumes that the link is broken and reports a link failure to the routing protocol. The routing protocol will remove this link. There exist two different reasons why a packet can not be sent to the next node. The first is if the node is out of reach due to mobility, the second is due to congestion. If the wireless medium is busy the link layer has to wait until it can transmit the packet. Depending on the queue length either the packet is dropped due to queue overflow or the link layer reports an error due to the timeout. If a node is in a congested area it is possible that all its paths to a destination are congested and they will be removed due to a reported link failure. A new route request has to be sent (increasing the load) and again only congested links can be found (as there exist only congested paths). Therefore the link layer detection may decrease the performance of the protocol as it is not possible to distinguish between broken and congested links. The higher the load in the network the higher the chance that links are congested and get removed by the routing protocol. This can be observed in Fig. 5.4. In the plot with higher load more route requests have to be sent compared to the plot with lower load. The average number of available paths is smaller if the load is higher, again due to the link layer detection.
Number of paths on average over time 2.5 # paths # paths time avg 2 number of paths

1.5

0.5

0 300

310

320 time [s]

330

340

350

Number of paths on average over time 2.5 # paths # paths time avg 2 number of paths

1.5

0.5

0 300

310

320 time [s]

330

340

350

Figure 5.4: Number of paths for a time interval, 1 and 2 packets/s per connection

26

5.2. Static Hexagonal Scenario

5.2.2. Number of Paths on Average


As scheduling makes only sense if it is possible to choose from more than one path, it is important to find out how many paths the protocol can really find. For the hexagonal hotspot scenario the number of paths found for longer distances approaches one. Even for paths with three hops, the average is below two (on average not always a choice) and consequentially, with this flooding method, scheduling makes sense only for paths with maximal three hops. The idea was to increase the throughput by routing around the bottleneck of the scenario, however this is not possible with three hops. Therefore the protocol is not suited for the given problem. It can also be seen that for higher load the number of paths found by a RREQ is lower as for a smaller load. The reason can be that more collisions can occur and the RREQ get lost or that they might be dropped due to full queues. The consequence is that less RREQ will reach the destination and less paths will be found.
Paths found on average for a shortest path with x hops (t>180) 7 6 5 4 10 3 2 1 0 1 2 3 4 hops 5 6 7 0 paths avg on time paths after one RREQ # connections number of connections number of connections 15 20

number of paths

Paths found on average for a shortest path with x hops (t>180) 7 6 5 4 10 3 2 1 0 1 2 3 4 hops 5 6 7 0 paths avg on time paths after one RREQ # connections 15 20

number of paths

Figure 5.5: Number of paths ordered with shortest path length, 1 and 2 packets/sec Even if a static scenario is used path can get lost (Sect. 4.1.1). The average number of paths depends on the load of the network. In Fig. 5.5 the average number of paths available during a simulation is plotted for two different loads. For higher load the average is lower and for paths with four hops or more the average is below one, this means that not at any time a path exists to the destination. The average number of available paths can be seen as a measure of the connectivity of the network. If no paths to a destination are available a RREQ has to be sent. The more often a route is deleted the more requests are sent. This results in an increased load of the network which will decrease the number of available paths. To find node or link disjoint paths, all first and last hops have to be unique and hence the number of neighbours defines the number of disjoint paths that can exist. In Fig. 5.6 an example of the flooding is plotted 27

5.2. Static Hexagonal Scenario

for a hotspot scenario. All the nodes that broadcast the request that has passed a specific first hop are coloured with the same colour. If a connection is constructed from source S to destination D1 only one path will be found, as D1 receives only RREQ that have been forwarded via node one. If a connection from S to D2 is created, two paths can be found as RREQs via node one and node two are received. Obviously the chance is small that D2 will ever receive a RREQ that has been forwarded from node five.

Figure 5.6: Concept of the flooding mechanism

5.2.3. Number of Dropped Packets Plotted as Area


As the idea is to increase the throughput, the bottleneck of the simulation has to be identified. Therefore the number of dropped packets divided by the total number of sent packets is plotted in the 2D area of the simulation. In Fig. 5.7 the results for the hotspot scenario with a load of 1, 2 and 4 packets/sec are illustrated. Light colours correspond to a high number of dropped packets, darker colours represent low numbers of dropped packets. The 50 connections are uniformly distributed over the nodes and hence the chance that many connections start and end in the hotspot is high. It can be seen that the hotspot is not the area with the highest probability that a packet is dropped. It can be concluded that the hotspot is not the bottleneck of the scenario but any further conclusions about the bottleneck would require new simulations to exclude any edge effects.

28

5.2. Static Hexagonal Scenario

Dropped data packets over total sent data packets 1500 0.01 0.008 0.006 1000 Y 0.004 0.002 0 500

0 0 500 X Dropped data packets over total sent data packets 1500 0.01 0.008 0.006 1000 Y 0.004 0.002 0 500 1000 1500

0 0 500 X Dropped data packets over total sent data packets 1500 0.01 0.008 0.006 1000 Y 0.004 0.002 0 500 1000 1500

0 0 500 X 1000 1500

Figure 5.7: Dropped packets plotted in a 2D area, 1, 2, and 4 packets/sec

29

5.2. Static Hexagonal Scenario

5.2.4. Routing Table


As the routing protocol has a large impact on the performance, it is interesting to see the behaviour of the protocol over time Sect. 4.1.3. In Fig. 5.8 the content of the routing tables has been used to construct all possible paths from source (red arrow) to destination (blue arrow). The destination can be reached with three hops and at this time instance four paths can be found.

Content of routing tables 1500 0.025 0.02 0.015 1000 Y Y 0.01 0.005 0 500

0 0 500 X 1000 1500

Figure 5.8: Content of the routing tables at a given time instant

5.2.4.1. Run Condition of AOMDV AOMDV uses flooding to set up a route from a source to a destination. All nodes that receive a RREQ store the information from which node the request has been sent and via which node it was received. The route replies will then be forwarded to the source of the request using this information. Each node decides if the received information will be used to add a new disjoint path. The backward paths are not removed, they only get a lifetime that is shorter than the lifetime of an active route (but they will live for 6 seconds). Until these path are expired, the routing table can contain entries that are not part of a disjoint path. As forwarding nodes select the first available path, without checking if the last hop is the one that was intended, it is possible that the paths in use will not be disjoint. In Fig. 5.9 can be seen that three route replies have been sent to the source but only two disjoint paths can be constructed. The backward paths are not removed and constructing path from the routing tables will return three not disjoint paths.

30

5.2. Static Hexagonal Scenario

Content of routing tables 1500 0.025 0.02 0.015 1000 Y Y 0.01 0.005 0 500

0 0 500 X 1000 1500

Figure 5.9: Run condition in AOMDV

31

32

6. Further Work
Based on the performed investigations and identified problems of AOMDV two directions for further work are proposed. The first is about a new protocol that does not suffer from the same problems as AOMDV, the second direction is about how to improve AOMDV to circumvent these problems.

6.1. AODV-Multipath
One of the main problems of AOMDV is that the flooding algorithm is not designed such that it will find many paths. Another protocol also based on AODV uses a different method of finding multiple paths. This protocol has been proposed in [14] and is called AODVM (AODV-Multipath). If a flooding is initiated intermediate nodes in AODV rebroadcast only one RREQ. In AODVM the duplicates of the RREQ are not discarded but their information are stored. For each RREQ the source, destination and last hop is stored. In contrast to AODV intermediate nodes are not allowed to send a RREP. All the RREP contain the information about the last hop over which the RREQ was received. For each RREQ received at the destination one RREP with the corresponding last hop information is generated and sent to the last hop. Any node receiving a RREP deletes the stored information of the corresponding RREQ and add a routing entry. The RREP is forwarded via the shortest path (that has not yet been used) to the source. Thanks to this enhanced flooding the protocol can find more paths than using the flooding mechanism of AODV. The results in [14] are promissing a quite high number of node-disjoint paths and therefore this protocol could be a candidate if multiple paths to a destination are required.

6.2. Improving AOMDV


One problem with AOMDV is that links are deleted when they seem to be failed. As the protocol can not distinguish between congested and broken links, highly congested paths are removed. If a node is in a congested area, it is possible that all paths will be highly loaded but removing these links and then initiating a new flooding does not solve the problem. The flooding will increase the load and the paths that will be found are still congested. Therefore it could make sense to prevent the protocol from removing congested links. But this requires a method to distinguish between congested and broken links for instance using Hello messages. This idea can only solve the problem of loosing paths over time but the problem of not finding enough paths remains. With the used flooding mechanism only a few paths can be found to a destination. To resolve this problem large changes on the flooding procedure are required. As AODVM already has proposed an enhanced way of flooding, selecting AODVM might be the more promising way than trying to improve AOMDV.

33

34

7. Conclusion
7.1. Timeplan
The thesis started with about two week to get familiar with the topic and the simulator. Then the different scheduling algorithms had to be implemented and evaluated. This work was done according to the time plan. As the scheduling did not show great influence on the performance the protocol was further investigated and no time was spent for developping new scheduling methods based on the original problem. As the protocol proved to be not suitable for multipath scheduling the direction of the work was changed and the new goal was to develop tools to show that the protocol is not suitable and perform simulations as a proof. Therefore the second part of the timeplan was not fullfiled and the new topics were planned according to the respective results.

7.2. Protocol
As basis for the thesis the AOMDV protocol should be used. But during the work this protocol showed different problems and the conclusion is that it can not be used for multipath scheduling. The main problem of AOMDV is that it uses a simple flooding mechanism to find paths to the destination. This is well suited for a protocol that uses one path and has the rest as backup. For scheduling over multiple paths, this flooding can not be used, as only some of the existing paths can be found, furthermore the longer the paths to a destination are, the less paths are found. As scheduling makes only sense if the paths do not influence each other (because of interference), short paths are not of interest however it is rare that more than one long path can be found. The second problem is that the protocol deletes congested paths as they can not be distinguished from broken paths. Deleting paths always increases the chance of sending new route requests and consequentially increase the load of the network. As a consequence, even if routes do not break due to mobility (static scenario) the number of paths from source to destination will decrease over time. The two above mentioned problems lead to the conclusion that AOMDV can not be used for multipath scheduling.

7.3. Goals Reached


As a start the simulator has been installed and different scheduling methods have been implemented. The scheduling function has been designed such that it allows easily to add new scheduling methods by adding a new case to the switch. The performance of the methods have been evaluated and compared to the original protocol. As the results were not satisfying different evaluation tools have been developed to investigate certain properties of the protocol. These tools have been designed such that they can be used with any protocol that can generate the same output. During the work it was shown that the protocol is not suited for the given problem formulation and therefore the goal was to show the different problems of AOMDV and investigate a special problem. The ques35

7.3. Goals Reached

tion whether node density is a good scheduling metric in a hotspot scenario has not been answered completely. As any answer is directly related to the underlying protocol, a conclusion would not be generally valid. It was shown that the hotspot is not the area with the highest drop rate but any further conclusion were not possible as the results didnt show a clear trend. To show the behaviour and the performance of the protocol different tools have been developed. These scripts can produce graphical output and visualise different aspects of the routing protocol. As the thesis was based on goals that have been defined during the work and the original goals have been omitted, the timeplan was not fullfiled and the original goals were only partly reached. The redefined goals have been reached as different scripts have been developed and the hotspot scenario has been evaluated.

36

Bibliography
[1] M. Marina and S. Das, On-demand Multipath Distance Vector Routing in Ad Hoc Networks, in IEEE International Conference on Network Protocols, 2001, pp. 1423. [2] E. Royer and C.-K. Toh, A Review of Current Routing Protocols for Ad-Hoc Mobile Wireless Networks, in IEEE Personal Communications, April 1999. [3] C. Perkins, E. Belding-Royer, and S. Das, RFC 3561, http://www.ietf.org/rfc/rfc3561.txt, July 2003. [4] S. Mueller, R. Tsang, and D. Ghosal, Multipath Routing in Mobile Ad Hoc Networks: Issues and Challenges, in Invited paper in Lecture Notes in Computer Science, 2004. [5] L. Zhang, Z. Zhao, Y. Shu, L. Wang, and O. Yang, Load Balancing of Multipath Source Routing in Ad Hoc Networks, in IEEE ICC 2002, 2001. [6] E. Royer, P. Melliar-Smith, and L. Moser, An Analysis of the Optimum Node Density for Ad Hoc Mobile Networks, in IEEE International Conference on Communications, June 2001. [7] K. Wu and J. Harms, Load-Sensitive Routing for Mobile Ad Hoc Networks, in 10th IEEE International Conference on Computer Communications and Networks, October 2001, pp. 540546. [8] H. Hassanein and A. Zhou, Routing with Load Balancing in Wireless Ad Hoc Networks, in 4th ACM International Workshop on Modeling, Analysis and Simulation of Wireless and Mobile Systems, 2001. [9] Network Simulator ns-2, http://www.isi.edu/nsnam/ns/. [10] M. Marina and S. Das, NS implementation of AOMDV, http://www.cs.sunysb.edu/mahesh/aomdv/. [11] Condor, http://computing.ee.ethz.ch/programming/condor.de.html. [12] Condor project homepage, http://www.cs.wisc.edu/condor/. [13] H. Dinsen-Hansen, Whirlgif, http://www.danbbs.dk/ dino/whirlgif/. [14] Z. Ye, S. Krishnamurthy, and S. Tripathi, A framework for Reliable Routing in Mobile Ad Hoc Networks, in NFOCOM 2003. Twenty-Second Annual Joint Conference of the IEEE Computer and Communications Societies. IEEE, 2003, pp. 270280.

37

38

A. Code
A.1. C++
A.1.1. aodv.h
/ Mode : C + + ; cb a s i c o f f s e t : 4 ; tabwidth : 4 ; i n d e n ttabsmode : t / / C o p y r i g h t ( c ) 1 9 9 7 , 1998 C a r n e g i e Mellon U n i v e r s i t y . A l l R i g h t s Reserved . P e r m i s s i o n t o use , copy , modify , and d i s t r i b u t e t h i s s o f t w a r e and i t s documentation i s h e r e b y gr a n t e d ( i n c l u d i n g f o r commercial o r f o r p r o f i t use ) , p r o v i d e d t h a t both t h e c o p y r i g h t n o t i c e and t h i s p e r m i s s i o n n o t i c e appear i n a l l c o p i e s o f t h e s o f t w a r e , d e r i v a t i v e works , o r m o d i f i e d v e r s i o n s , and any p o r t i o n s t h e r e o f , and t h a t both n o t i c e s appear i n s u p p o r t i n g documentation , and t h a t c r e d i t i s g i v e n t o C a r n e g i e Mellon U n i v e r s i t y i n a l l p u b l i c a t i o n s r e p o r t i n g on d i r e c t o r i n d i r e c t use o f t h i s code o r i t s d e r i v a t i v e s . ALL CODE , SOFTWARE , PROTOCOLS , AND ARCHITECTURES DEVELOPED BY THE CMU MONARCH PROJECT ARE EXPERIMENTAL AND ARE KNOWN TO HAVE BUGS , SOME OF WHICH MAY HAVE SERIOUS CONSEQUENCES . CARNEGIE MELLON PROVIDES T H I S SOFTWARE OR OTHER INTELLECTUAL PROPERTY IN I T S AS I S CONDITION , AND ANY EXPRESS OR IMPLIED WARRANTIES , INCLUDING , BUT NOT LIMITED TO , THE IMPLIED WARRANTIES OF MERCHANTABILITY AND F I T N E S S FOR A PARTICULAR PURPOSE ARE DISCLAIMED . IN NO EVENT SHALL CARNEGIE MELLON UNIVERSITY BE L I A B L E FOR ANY DIRECT , INDIRECT , INCIDENTAL , S P E C I A L , EXEMPLARY , OR CONSEQUENTIAL DAMAGES ( INCLUDING , BUT NOT LIMITED TO , PROCUREMENT OF SUBSTITUTE GOODS OR S E R V I C E S ; LOSS OF USE , DATA , OR P R O F I T S ; OR BUSINESS INTERRUPTION ) HOWEVER CAUSED AND ON ANY THEORY OF L I A B I L I T Y , WHETHER IN CONTRACT , S T R I C T L I A B I L I T Y , OR TORT ( INCLUDING NEGLIGENCE OR OTHERWISE ) ARISING IN ANY WAY OUT OF THE USE OF T H I S SOFTWARE OR INTELLECTUAL PROPERTY , EVEN I F ADVISED OF THE P O S S I B I L I T Y OF SUCH DAMAGE . C a r n e g i e Mellon e n c o u r a ge s ( but does not r e q u i r e ) u s e r s o f t h i s s o f t w a r e o r i n t e l l e c t u a l p r o p e r t y t o r e t u r n any improvements o r e x t e n s i o n s t h a t t h e y make , and t o gr a n t C a r n e g i e Mellon t h e r i g h t s t o r e d i s t r i b u t e t h e s e changes w i t h o u t encumbrance . The AODV code d e v e l o p e d by t h e CMU/MONARCH group was o p t i m i z e d and tuned by Samir Das and Mahesh Marina , U n i v e r s i t y o f C i n c i n n a t i . The work was p a r t i a l l y done i n Sun M i c r o s y s t e m s . # # P r o j e c t : S e m e s t e r T h e s i s S S 06: # E v a l u a t i o n o f s c h e d u l i n g methods o v e r # m u l t i p a t h r o u t i n g i n w i r e l e s s m o b i l e Ad Hoc n e t w o r k s # # A u t h o r s : R e gu l a Goenner , Dominik Schatzmann # # # Date : J u l y 2006 # # The code has been m o d i e f i e d by R . Goenner and D . Schatzmann , # m o d i f i c a t i o n s a r e i n d i c a t e d with t h e tag / / [ s c h e d u l i n g ] # and t h e y can be a c t i v a t e d by u s i n g # d e f i n e SA_CHANGE # / # i f n d e f __aodv_h__ #d e f i n e __aodv_h__

39

A.1. C++

#i n c l u d e #i n c l u d e #i n c l u d e #i n c l u d e #i n c l u d e

< iostream > <cmut r a c e . h> < p r i q ueue . h> < aodv / a o d v _ r t a b l e . h> < aodv / aodv_rqueue . h>

# i f d e f AOMDV #d e f i n e AOMDV_PACKET_SALVAGING #d e f i n e AOMDV_MAX_SALVAGE_COUNT #e n d i f / / AOMDV #d e f i n e AODV_EXPANDING_RING_SEARCH / Allows l o c a l r e p a i r of routes / / /# d e f i n e AODV_LOCAL_REPAIR

10

/ A l l o w s AODV t o use l i n k l a y e r ( 8 0 2 . 1 1 ) f e e d b a c k i n d e t e r m i n i n g when l i n k s a r e up /down . / #d e f i n e AODV_LINK_LAYER_DETECTION #d e f i n e AODV_HELLO / / [ s c h e d u l i n g ] / / # d e f i n e AODV_PING #d e f i n e AODV_INFO / / # d e f i n e SA_DEBUG / / [ s c h e d u l i n g ] end / C a u s e s AODV t o a p p l y a " smoothing " f u n c t i o n t o t h e l i n k l a y e r f e e d b a c k t h a t i s ge n e r a t e d by 8 0 2 . 1 1 . I n e s s e n c e , i t r e q u i r e s t h a t RT_MAX_ERROR e r r o r s o c c u r s w i t h i n a window o f RT_MAX_ERROR_TIME b e f o r e t h e l i n k i s c o n s i d e r e d bad . / #d e f i n e AODV_USE_LL_METRIC / Only a p p l i e s i f AODV_USE_LL_METRIC i s d e f i n e d . C a u s e s AODV t o a p p l y o m n i s c i e n t knowledge t o t h e f e e d b a c k r e c e i v e d from 8 0 2 . 1 1 . T h i s may be flawed , b e c a u s e i t does not a c c o u n t f o r congestion . / / /# d e f i n e AODV_USE_GOD_FEEDBACK c l a s s AODV ; #d e f i n e MY_ROUTE_TIMEOUT 10 #d e f i n e ACTIVE_ROUTE_TIMEOUT 10 #d e f i n e REV_ROUTE_LIFE 6 #d e f i n e BCAST_ID_SAVE 6

// // // //

10 s e c o n d s 10 s e c o n d s 6 seconds 6 seconds

/ / [ s c h e d u l i n g ] / / we need a t i m e o u t f o r each path , s e t i t t h e same as t h e r o u t e t i m e o u t #d e f i n e ACTIVE_PATH_TIMEOUT 10 / / 10 s e c o n d s / / [ s c h e d u l i n g ] end / / No . o f t i m e s t o do networkwide s e a r c h b e f o r e t i m i n g out f o r / / MAX_RREQ_TIMEOUT s e c . #d e f i n e RREQ_RETRIES 3 / / t i m e o u t a f t e r doing networkwide s e a r c h RREQ_RETRIES t i m e s #d e f i n e MAX_RREQ_TIMEOUT 10.0 // sec / / S h o u l d be s e t by t h e u s e r u s i n g b e s t gu e s s ( c o n s e r v a t i v e ) #d e f i n e NETWORK_DIAMETER 30 / / 30 hops / V a r i o u s c o n s t a n t s used f o r t h e expanding r i n g s e a r c h / # i f d e f AODV_EXPANDING_RING_SEARCH

40

A.1. C++

#d e f i n e TTL_START 5 // 5 #d e f i n e TTL_INCREMENT 2 // 2 # e l s e / / NO EXPANDING RING SEARCH #d e f i n e TTL_START NETWORK_DIAMETER #d e f i n e TTL_INCREMENT NETWORK_DIAMETER #e n d i f / / NO EXPANDING RING SEARCH #d e f i n e TTL_THRESHOLD 7

// 5 // 2

/ / T h i s s h o u l d be somewhat r e l a t e d t o arp t i m e o u t #d e f i n e NODE_TRAVERSAL_TIME 0.03 / / 30 ms #d e f i n e LOCAL_REPAIR_WAIT_TIME 0 . 1 5 // sec / / Must be l a r g e r than t h e time d i f f e r e n c e between a node p r o p a ga t e s a r o u t e / / r e q u e s t and g e t s t h e r o u t e r e p l y back . #d e f i n e RREP_WAIT_TIME #d e f i n e ID_NOT_FOUND #d e f i n e ID_FOUND 1.0 0x00 0x01 // sec

/ / The f o l l o w i n g s a r e used f o r t h e f o r w a r d ( ) f u n c t i o n . C o n t r o l s p a c i n g . #d e f i n e DELAY 1.0 / / random d e l a y #d e f i n e NO_DELAY 1.0 / / no d e l a y / / t h i n k i t s h o u l d be 30 ms #d e f i n e ARP_DELAY 0.01 #d e f i n e #d e f i n e #d e f i n e #d e f i n e #d e f i n e HELLO_INTERVAL ALLOWED_HELLO_LOSS BAD_LINK_LIFETIME MaxHelloInterval MinHelloInterval / / f i x e d d e l a y t o keep arp happy

1 / / 1000 ms 3 // packets 3 / / 3000 ms ( 1 . 2 5 HELLO_INTERVAL ) ( 0 . 7 5 HELLO_INTERVAL ) 4 // 4s

/ / [ s c h e d u l i n g ] #d e f i n e PING_INTERVAL / / [ s c h e d u l i n g ] end

/ T i m e r s ( B r o a d c a s t ID , H e l l o , Neighbor Cache , Route Cache ) / c l a s s Br o ad cas t T i m er : p u b l i c Handler { public : Br o ad cas t T i m er ( AODV a ) : agent ( a ) { } v o i d handle ( Event ) ; private : AODV agent ; Event i n t r ; }; c l a s s H el l o T i m er : p u b l i c Handler { public : H el l o T i m er ( AODV a ) : agent ( a ) { } v o i d handle ( Event ) ; private : AODV agent ; Event i n t r ; }; c l a s s NeighborTimer : p u b l i c Handler { public : NeighborTimer ( AODV a ) : agent ( a ) { } v o i d handle ( Event ) ; private :

41

A.1. C++

AODV agent ; Event i n t r ; }; c l a s s RouteCacheTimer : p u b l i c Handler { public : RouteCacheTimer ( AODV a ) : agent ( a ) { } v o i d handle ( Event ) ; private : AODV agent ; Event i n t r ; }; c l a s s L o c a l R e p a i r T i m e r : p u b l i c Handler { public : L o c a l R e p a i r T i m e r ( AODV a ) : agent ( a ) { } v o i d handle ( Event ) ; private : AODV agent ; Event i n t r ; }; / / [ s c h e d u l i n g ] # i f d e f SA_CHANGE c l a s s PingTimer : p u b l i c Handler { public : PingTimer ( AODV a ) : agent ( a ) { } v o i d handle ( Event ) ; private : AODV agent ; Event i n t r ; }; #e n d i f / / [ s c h e d u l i n g ] end # i f d e f AOMDV / Route L i s t / c l a s s AODV_Route { f r i end cl as s BroadcastID ; public : AODV_Route ( ns ad d r _ t nexthop , ns ad d r _ t l a s t h o p =0) { nh_addr = nexthop ; l h_ ad d r = l a s t h o p ; } protected : LIST_ENTRY ( AODV_Route ) r o u t e _ l i n k ; ns ad d r _ t nh_addr ; ns ad d r _ t l h_ ad d r ; / / [ s c h e d u l i n g ] # i f d e f SA_CHANGE i n t s ched _ t y p e ; #e n d i f / / [ s c h e d u l i n g ] end }; LIST_HEAD ( aodv_routes , AODV_Route ) ; #e n d i f / / AOMDV

/ B r o a d c a s t ID Cache / cl as s BroadcastID

42

A.1. C++

{ f r i e n d c l a s s AODV ; public : B r o a d c a s t I D ( ns ad d r _ t i , u _ i n t 3 2 _ t b ) { src = i ; id = b ; # i f d e f AOMDV count =0; L I S T _ I N I T (& r e v e r s e _ p a t h _ l i s t ) ; L I S T _ I N I T (& f o r w a r d _ p a t h _ l i s t ) ; #e n d i f / / AOMDV } protected : LIST_ENTRY ( B r o a d c a s t I D ) l i n k ; ns ad d r _ t s r c ; u_int32_t id ; double e x p i r e ; / / now + BCAST_ID_SAVE s # i f d e f AOMDV i n t count ; / / L i s t o f r e v e r s e p a t h s used f o r f o r w a r d i n g r e p l i e s ao d v _ r o ut es r e v e r s e _ p a t h _ l i s t ; / / L i s t of forward paths a d v e r t i s e d a l rea d y ao d v _ r o ut es f o r w a r d _ p a t h _ l i s t ; i n l i n e AODV_Route r e v e r s e _ p a t h _ i n s e r t ( ns ad d r _ t nexthop , ns ad d r _ t l a s t h o p =0) { AODV_Route r o ut e = new AODV_Route ( nexthop , l a s t h o p ) ; a s s e r t ( r o ut e ) ; LIST_INSERT_HEAD (& r e v e r s e _ p a t h _ l i s t , route , r o u t e _ l i n k ) ; r e t u r n r o ut e ; } i n l i n e AODV_Route r e v e r s e _ p a t h _ l o o k u p ( ns ad d r _ t nexthop , ns ad d r _ t l a s t h o p =0) { AODV_Route r o ut e = r e v e r s e _ p a t h _ l i s t . l h _ f i r s t ; / / S e a r c h t h e l i s t f o r a match o f i d f o r ( ; r o ut e ; r o ut e = route > r o u t e _ l i n k . l e _ n e x t ) { i f ( ( route >nh_addr == nexthop ) && ( route >l h_ ad d r == l a s t h o p ) ) r e t u r n r o ut e ; } r e t u r n NULL ; } i n l i n e AODV_Route f o r w a r d _ p a t h _ i n s e r t ( ns ad d r _ t nexthop , ns ad d r _ t l a s t h o p =0) { AODV_Route r o ut e = new AODV_Route ( nexthop , l a s t h o p ) ; a s s e r t ( r o ut e ) ; LIST_INSERT_HEAD (& f o r w a r d _ p a t h _ l i s t , route , r o u t e _ l i n k ) ; r e t u r n r o ut e ; } i n l i n e AODV_Route f o r w ar d _ p at h_ lo okup ( ns ad d r _ t nexthop , ns ad d r _ t l a s t h o p =0) { AODV_Route r o ut e = f o r w a r d _ p a t h _ l i s t . l h _ f i r s t ; / / S e a r c h t h e l i s t f o r a match o f i d f o r ( ; r o ut e ; r o ut e = route > r o u t e _ l i n k . l e _ n e x t )

43

A.1. C++

{ i f ( ( route >nh_addr == nexthop ) && r e t u r n r o ut e ; } r e t u r n NULL ; } #e n d i f / / AOMDV }; LIST_HEAD ( aodv_bcache , B r o a d c a s t I D ) ; ( route >l h_ ad d r == l a s t h o p ) )

/ A s t r u c t t o s t o r e i n f o s about t h e c u r r e n t node / # i f d e f AODV_INFO struct info { ns ad d r _ t ns ad d r _ t int int ns ad d r _ t ns ad d r _ t int double

src ; dst ; action ; path_count ; next_hop ; last_hop ; hop_count ; rtt ;

// // // // // // // //

s r c o f t h e path d e s t i n a t i o n o f t h e path a c t i o n ( add o r remove ) number o f path t o d e s t n e x t hop o f t h e path l a s t hop o f t h e path number o f hops t o t h e d e s t i n a t i o n r t t o v e r t h i s path

}; #e n d i f / / INFO

/ The R o u t i n g Agent / c l a s s AODV : p u b l i c Agent { / make some f r i e n d s f i r s t / f r i end cl as s aodv_rt_entry ; / / [ s c h e d u l i n g ] # i f d e f SA_CHANGE f r i e n d c l a s s AODV_path ; #e n d i f / / [ s c h e d u l i n g ] end f r i e n d c l a s s Br o ad cas t T i m er ; f r i e n d c l a s s H el l o T i m er ; f r i e n d c l a s s NeighborTimer ; f r i e n d c l a s s RouteCacheTimer ; f r i end cl as s LocalRepairTimer ; / / [ s c h e d u l i n g ] # i f d e f SA_CHANGE # i f d e f AODV_PING f r i e n d c l a s s PingTimer ; #e n d i f # i f d e f AODV_INFO f r i end cl as s InfoTimer ; #e n d i f #e n d i f / / [ s c h e d u l i n g ] end

44

A.1. C++

public : AODV ( ns ad d r _ t i d ) ; v o i d r e c v ( Packet p , Handler ) ; protected : i n t command ( i n t , co ns t char co ns t ) ; i n t i n i t i a l i z e d ( ) { r e t u r n 1 && t a r g e t _ ; } / Route T a b l e Management / v o i d r t _ r e s o l v e ( Packet p ) ; # i f n d e f AOMDV v o i d r t _ up d at e ( a o d v _ r t _ e n t r y r t , u _ i n t 3 2 _ t seqnum , u _ i n t 1 6 _ t m et r i c , ns ad d r _ t nexthop , double e x p i r e _ t i m e ) ; #e n d i f / / AOMDV v o i d rt_down ( a o d v _ r t _ e n t r y r t ) ; v o i d l o c a l _ r t _ r e p a i r ( a o d v _ r t _ e n t r y r t , Packet p ) ; public : v o i d r t _ l l _ f a i l e d ( Packet p ) ; # i f n d e f AOMDV v o i d h a n d l e _ l i n k _ f a i l u r e ( ns ad d r _ t i d ) ; #else v o i d h a n d l e _ l i n k _ f a i l u r e ( ns ad d r _ t id , b o o l e r r o r = t r u e ) ; #e n d i f protected : void rt_purge ( void ) ; v o i d enque ( a o d v _ r t _ e n t r y r t , Packet p ) ; Packet deque ( a o d v _ r t _ e n t r y r t ) ; / Neighbor Management / v o i d n b _ i n s e r t ( ns ad d r _ t i d ) ; AODV_Neighbor nb_lookup ( ns ad d r _ t i d ) ; v o i d nb _ d el et e ( ns ad d r _ t i d ) ; v o i d nb_purge ( v o i d ) ; / B r o a d c a s t ID Management / B r o a d c a s t I D i d _ i n s e r t ( ns ad d r _ t id , u _ i n t 3 2 _ t b i d ) ; B r o a d c a s t I D i d _ l o o k u p ( ns ad d r _ t id , u _ i n t 3 2 _ t b i d ) ; v o i d i d _ p ur g e ( v o i d ) ; / P a c k e t TX R o u t i n e s / v o i d forward ( a o d v _ r t _ e n t r y r t , Packet p , double d e l a y ) ; v o i d f o r w ar d R ep l y ( a o d v _ r t _ e n t r y r t , Packet p , double d e l a y ) ; v o i d s end H el l o ( v o i d ) ; v o i d sendRequest ( ns ad d r _ t d s t ) ; / / [ s c h e d u l i n g ] # i f d e f SA_CHANGE # i f d e f AODV_PING v o i d sendPing ( v o i d ) ; v o i d sendPong ( ns ad d r _ t dest , Packet p ) ; #e n d i f # i f d e f AODV_INFO v o i d s end I nf o ( ) ; v o i d dumpPath ( a o d v _ r t _ e n t r y r t , AODV_Path path , i n t act i o n , i n t num_path ) ;

45

A.1. C++

#e n d i f #e n d i f / / [ s c h e d u l i n g ] end # i f n d e f AOMDV v o i d s end R ep l y ( ns ad d r _ t i p d s t , u_int32_t hop_count , ns ad d r _ t rpdst , u_int32_t rpseq , u_int32_t lifetime , double timestamp ) ; #e l s e / / AOMDV v o i d s end R ep l y ( ns ad d r _ t i p d s t , u_int32_t hop_count , ns ad d r _ t rpdst , u_int32_t rpseq , u_int32_t lifetime , double timestamp , ns ad d r _ t nexthop , u_int32_t bcast_id , ns ad d r _ t rp_first_hop ) ; #e n d i f / / AOMDV v o i d s e n d E r r o r ( Packet p , b o o l j i t t e r = t r u e ) ; / P a c k e t RX Routinesaomdv_max_paths_ / v o i d recvAODV ( Packet p ) ; v o i d r e c v H e l l o ( Packet p ) ; v o i d r ecv R eq ues t ( Packet p ) ; v o i d r e c v R e p l y ( Packet p ) ; v o i d r e c v E r r o r ( Packet p ) ; / / [ s c h e d u l i n g ] # i f d e f SA_CHANGE # i f d e f AODV_PING v o i d r e c v P i n g ( Packet p ) ; #e n d i f #e n d i f / / [ s c h e d u l i n g ] end / H i s t o r y management / double PerHopTime ( a o d v _ r t _ e n t r y r t ) ; ns ad d r _ t i nd ex ; u _ i n t 3 2 _ t seqno ; i n t bid ; a o d v _ r t a b l e r t head ; aodv_ncache nbhead ; aodv_bcache bihead ; / / [ s c h e d u l i n g ] # i f d e f SA_CHANGE i n t s ched _ t y p e ; #e n d i f / / [ s c h e d u l i n g ] end / Timers / Br o ad cas t T i m er H el l o T i m er NeighborTimer RouteCacheTimer / / I P A d d r e s s o f t h i s node / / Sequence Number / / B r o a d c a s t ID // routing table / / Neighbor Cache / / B r o a d c a s t ID Cache

// scheduler type

btimer ; htimer ; ntimer ; rtimer ;

46

A.1. C++

LocalRepairTimer lrtimer ; / / [ s c h e d u l i n g ] # i f d e f SA_CHANGE PingTimer ptimer ; #e n d i f / / [ s c h e d u l i n g ] end / Routing Table / aodv_rtable r t ab l e ; / A " dropf r o n t " queue used by t h e r o u t i n g l a y e r t o b u f f e r p a c k e t s t o which i t does not have a r o u t e . / aodv_rqueue rqueue ; / A mechanism f o r l o g g i n g t h e c o n t e n t s o f t h e r o u t i n g table . / T r ace l o g t a r g e t ; / A p o i n t e r t o t h e network i n t e r f a c e queue t h a t s i t s between t h e " c l a s s i f i e r " and t h e " l i n k l a y e r " . / PriQueue i f q ueue ; / L o ggi n g s t u f f / v o i d l o g _ l i n k _ d e l ( ns ad d r _ t d s t ) ; v o i d l o g _ l i n k _ b r o k e ( Packet p ) ; v o i d l o g _ l i n k _ k e p t ( ns ad d r _ t d s t ) ; # i f d e f AOMDV i n t aomdv_max_paths_ ; i n t ao m d v _ p r i m _ a l t _ p a t h _ l e n _ d i f f _ ; #e n d i f / /AOMDV / / [ s c h e d u l i n g ] # i f d e f SA_CHANGE # i f d e f AODV_INFO i n f o no d e_ i nf o ; / / s t r u c t t o s t o r e i n f o r m a t i o n s #e n d i f #e n d i f / / [ s c h e d u l i n g ] end }; #e n d i f / __aodv_h__ /

Listing A.1: aodv.h

47

A.1. C++

A.1.2. aodv.cc
/ Mode : C + + ; cb a s i c o f f s e t : 4 ; tabwidth : 4 ; i n d e n ttabsmode : t / / C o p y r i g h t ( c ) 1 9 9 7 , 1998 C a r n e g i e Mellon U n i v e r s i t y . A l l R i g h t s Reserved . P e r m i s s i o n t o use , copy , modify , and d i s t r i b u t e t h i s s o f t w a r e and i t s documentation i s h e r e b y gr a n t e d ( i n c l u d i n g f o r commercial o r f o r p r o f i t use ) , p r o v i d e d t h a t both t h e c o p y r i g h t n o t i c e and t h i s p e r m i s s i o n n o t i c e appear i n a l l c o p i e s o f t h e s o f t w a r e , d e r i v a t i v e works , o r m o d i f i e d v e r s i o n s , and any p o r t i o n s t h e r e o f , and t h a t both n o t i c e s appear i n s u p p o r t i n g documentation , and t h a t c r e d i t i s g i v e n t o C a r n e g i e Mellon U n i v e r s i t y i n a l l p u b l i c a t i o n s r e p o r t i n g on d i r e c t o r i n d i r e c t use o f t h i s code o r i t s d e r i v a t i v e s . ALL CODE , SOFTWARE , PROTOCOLS , AND ARCHITECTURES DEVELOPED BY THE CMU MONARCH PROJECT ARE EXPERIMENTAL AND ARE KNOWN TO HAVE BUGS , SOME OF WHICH MAY HAVE SERIOUS CONSEQUENCES . CARNEGIE MELLON PROVIDES T H I S SOFTWARE OR OTHER INTELLECTUAL PROPERTY IN I T S AS I S CONDITION , AND ANY EXPRESS OR IMPLIED WARRANTIES , INCLUDING , BUT NOT LIMITED TO , THE IMPLIED WARRANTIES OF MERCHANTABILITY AND F I T N E S S FOR A PARTICULAR PURPOSE ARE DISCLAIMED . IN NO EVENT SHALL CARNEGIE MELLON UNIVERSITY BE L I A B L E FOR ANY DIRECT , INDIRECT , INCIDENTAL , S P E C I A L , EXEMPLARY , OR CONSEQUENTIAL DAMAGES ( INCLUDING , BUT NOT LIMITED TO , PROCUREMENT OF SUBSTITUTE GOODS OR S E R V I C E S ; LOSS OF USE , DATA , OR P R O F I T S ; OR BUSINESS INTERRUPTION ) HOWEVER CAUSED AND ON ANY THEORY OF L I A B I L I T Y , WHETHER IN CONTRACT , S T R I C T L I A B I L I T Y , OR TORT ( INCLUDING NEGLIGENCE OR OTHERWISE ) ARISING IN ANY WAY OUT OF THE USE OF T H I S SOFTWARE OR INTELLECTUAL PROPERTY , EVEN I F ADVISED OF THE P O S S I B I L I T Y OF SUCH DAMAGE . C a r n e g i e Mellon e n c o u r a ge s ( but does not r e q u i r e ) u s e r s o f t h i s s o f t w a r e o r i n t e l l e c t u a l p r o p e r t y t o r e t u r n any improvements o r e x t e n s i o n s t h a t t h e y make , and t o gr a n t C a r n e g i e Mellon t h e r i g h t s t o r e d i s t r i b u t e t h e s e changes w i t h o u t encumbrance . The AODV code d e v e l o p e d by t h e CMU/MONARCH group was o p t i m i z e d and tuned by Samir Das and Mahesh Marina , U n i v e r s i t y o f C i n c i n n a t i . The work was p a r t i a l l y done i n Sun M i c r o s y s t e m s . M o d i f i e d f o r g r a t u i t o u s r e p l i e s by Anant U t g i k a r , 0 9 / 1 6 / 0 2 . # # P r o j e c t : S e m e s t e r T h e s i s S S 06: # E v a l u a t i o n o f s c h e d u l i n g methods o v e r # m u l t i p a t h r o u t i n g i n w i r e l e s s m o b i l e Ad Hoc n e t w o r k s # # A u t h o r s : R e gu l a Goenner , Dominik Schatzmann # # # Date : J u l y 2006 # # The code has been m o d i e f i e d by R . Goenner and D . Schatzmann , # m o d i f i c a t i o n s a r e i n d i c a t e d with t h e tag / / [ s c h e d u l i n g ] # and t h e y can be a c t i v a t e d by u s i n g # d e f i n e SA_CHANGE # / / /# i n c l u d e < i p . h> #i n c l u d e #i n c l u d e #i n c l u d e #i n c l u d e #i n c l u d e < aodv / aodv . h> < aodv / aodv_packet . h> <random . h> <cmut r a c e . h> < iostream >

#d e f i n e max ( a , b ) ( ( a ) > ( b ) ? ( a ) : ( b ) ) #d e f i n e NOW Sched ul er : : i n s t a n c e ( ) . c l o c k ( ) / /# d e f i n e DEBUG / /# d e f i n e ERROR

48

A.1. C++

#ifdef static static static #e n d i f

DEBUG i n t ext r a_r o ut e_r eply = 0; i n t limit _r o ut e_r eques t = 0; i n t route_request = 0;

/ TCL Hooks / i n t hdr_aodv : : o f f s e t _ ; s t a t i c c l a s s AODVHeaderClass : p u b l i c Packet H ead e r C l a s s { public : AODVHeaderClass ( ) : Packet H ead e r C l a s s ( " PacketHeader /AODV" , s i z e o f ( h d r _ a l l _ a o d v ) ) { b i n d _ o f f s e t (& hdr_aodv : : o f f s e t _ ) ; } } cl as s _ r t Pr o t o AO D V _ hd r ; s t a t i c c l a s s AODVclass : p u b l i c T c l C l a s s { public : AODVclass ( ) : T c l C l a s s ( " Agent /AODV" ) { } T c l O b j e c t c r e a t e ( i n t argc , co ns t char co ns t ar g v ) { a s s e r t ( ar g c == 5 ) ; r e t u r n ( new AODV ( ( ns ad d r _ t ) Address : : i n s t a n c e ( ) . s t r 2 a d d r ( ar g v [ 4 ] ) ) ) ; } } cl as s _ r t Pr o t o AO D V ;

i n t AODV : : command ( i n t argc , co ns t char co ns t ar g v ) { i f ( ar g c == 2 ) { T c l& t c l = T c l : : i n s t a n c e ( ) ; i f ( strncasecmp ( ar g v [ 1 ] , " i d " , 2 ) == 0) { t c l . r e s u l t f ( "%d " , i nd ex ) ; r e t u r n TCL_OK ; } i f ( strncasecmp ( ar g v [ 1 ] , "dumpt a b l e " , 1 0 ) == 0) { p r i n t f ( " Node %d : Route t a b l e : \ n " , i nd ex ) ; r t a b l e . rt_dumptable ( ) ; r e t u r n TCL_OK ; } i f ( strncasecmp ( ar g v [ 1 ] , " s t a r t " , 2 ) == 0) { btimer . handle ( ( Event ) 0 ) ; #i f n d e f AODV_LINK_LAYER_DETECTION htimer . handle ( ( Event ) 0 ) ; ntimer . handle ( ( Event ) 0 ) ; #e n d i f / / L I N K LAYER DETECTION

# i f d e f AODV_HELLO htimer . handle ( ( Event ) 0 ) ; ntimer . handle ( ( Event ) 0 ) ; #e n d i f / / AODV HELLO r t i m e r . handle ( ( Event ) 0 ) ; / / [ s c h e d u l i n g ]

49

A.1. C++

# i f d e f SA_CHANGE # i f d e f AODV_PING ptimer . handle ( ( Event ) 0 ) ; #e n d i f #e n d i f / / [ s c h e d u l i n g ] end r e t u r n TCL_OK ; } } e l s e i f ( ar g c == 3 ) { i f ( strcmp ( ar g v [ 1 ] , " i nd ex " ) == 0) { i nd ex = a t o i ( ar g v [ 2 ] ) ; r e t u r n TCL_OK ; } e l s e i f ( strcmp ( ar g v [ 1 ] , " logt a r g e t " ) == 0 | | strcmp ( ar g v [ 1 ] , " t r a c e t a r g e t " ) == 0) { l o g t a r g e t = ( T r ace ) T c l O b j e c t : : lookup ( ar g v [ 2 ] ) ; i f ( l o g t a r g e t == 0) r e t u r n TCL_ERROR ; r e t u r n TCL_OK ; } e l s e i f ( strcmp ( ar g v [ 1 ] , " dropt a r g e t " ) == 0) { i n t s t a t = rqueue . command ( argc , ar g v ) ; i f ( s t a t ! = TCL_OK ) r e t u r n s t a t ; r e t u r n Agent : : command ( argc , ar g v ) ; } e l s e i f ( strcmp ( ar g v [ 1 ] , " i f queue " ) == 0) { i f q ueue = ( PriQueue ) T c l O b j e c t : : lookup ( ar g v [ 2 ] ) ; i f ( i f q ueue == 0) r e t u r n TCL_ERROR ; r e t u r n TCL_OK ; } } r e t u r n Agent : : command ( argc , ar g v ) ; } / Constructor / # i f d e f SA_CHANGE AODV : : AODV ( ns ad d r _ t i d ) : Agent ( PT_AODV ) , btimer ( t h i s ) , htimer ( t h i s ) , ntimer ( t h i s ) , r t i m e r ( t h i s ) , l r t i m e r ( t h i s ) , ptimer ( t h i s ) , rqueue ( ) #else AODV : : AODV ( ns ad d r _ t i d ) : Agent ( PT_AODV ) , btimer ( t h i s ) , htimer ( t h i s ) , ntimer ( t h i s ) , r t i m e r ( t h i s ) , l r t i m e r ( t h i s ) , rqueue ( ) #e n d i f { # i f d e f AOMDV / / aomdv_max_paths_ = 2 ; bind ( " aomdv_max_paths_ " , &aomdv_max_paths_ ) ; / / [ s c h e d u l i n g ] # i f d e f SA_CHANGE r t a b l e . aomdv_max_paths_= aomdv_max_paths_ ; // s e t i t i n the r t a b l e ao m d v _ p r i m _ al t _ p a t h _ l e n_ d i f f _ = 1 5 ; / / o r i g i n a l s e t t i n g was 5 #else / / [ s c h e d u l i n g ] end r t a b l e . aomdv_max_paths_= aomdv_max_paths_ ; // s e t i t i n the r t a b l e ao m d v _ p r i m _ al t _ p a t h _ l e n_ d i f f _ = 5 ; #e n d i f

50

A.1. C++

#e n d i f / /AOMDV i nd ex = i d ; seqno = 2 ; bid = 1 ; / / [ s c h e d u l i n g ] # i f d e f SA_CHANGE bind ( " s ched _ t y p e " , &s ched _ t y p e ) ; r t a b l e . s ched _ t y p e = s ched _ t y p e ; #e n d i f / / [ s c h e d u l i n g ] end L I S T _ I N I T (&nbhead ) ; L I S T _ I N I T (& bihead ) ; lo gt ar get = 0; i f q ueue = 0 ; } / Timers / v o i d Br o ad cas t T i m er : : handle ( Event ) { agent >i d _ p ur g e ( ) ; Sched ul er : : i n s t a n c e ( ) . s ched ul e ( t h i s , &i n t r , BCAST_ID_SAVE ) ; }

v o i d H el l o T i m er : : handle ( Event ) { / Do not send a HELLO message u n l e s s we have a v a l i d r o u t e e n t r y . / i f ( agent > r t a b l e . r t _ h a s _ a c t i v e _ r o u t e ( ) ) agent >s end H el l o ( ) ; / / CHANGE double i n t e r v a l = HELLO_INTERVAL + 0 . 0 1 Random : : uniform ( ) ; a s s e r t ( i n t e r v a l >= 0 ) ; Sched ul er : : i n s t a n c e ( ) . s ched ul e ( t h i s , &i n t r , i n t e r v a l ) ; } v o i d NeighborTimer : : handle ( Event ) { agent >nb_purge ( ) ; Sched ul er : : i n s t a n c e ( ) . s ched ul e ( t h i s , &i n t r , HELLO_INTERVAL ) ; }

v o i d RouteCacheTimer : : handle ( Event ) { agent >r t _ p u r g e ( ) ; #d e f i n e FREQUENCY 0 . 5 / / s e c Sched ul er : : i n s t a n c e ( ) . s ched ul e ( t h i s , &i n t r , FREQUENCY ) ; } v o i d L o c a l R e p a i r T i m e r : : handle ( Event p ) / / SRD : 5/4/99 { aodv_rt_entry r t ; s t r u c t h d r _ i p i h = HDR_IP ( ( Packet ) p ) ; / you ge t h e r e a f t e r t h e t i m e o u t i n a l o c a l r e p a i r attempt / / f p r i n t f ( s t d e r r , "% s \ n " , __FUNCTION__ ) ; / r t = agent > r t a b l e . r t _ l o o k u p ( ih >daddr ( ) ) ; i f ( r t && r t > r t _ f l a g s ! = RTF_UP )

51

A.1. C++

{ // // // / / r o u t e i s y e t t o be r e p a i r e d I w i l l be c o n s e r v a t i v e and b r i n g down t h e r o u t e and send r o u t e e r r o r s upstream . The f o l l o w i n g a s s e r t f a i l s , not s u r e why / a s s e r t ( r t > r t _ f l a g s == R T F _ I N _ R E P A I R ) ; /

agent >rt_down ( r t ) ; / / send RERR # i f d e f DEBUG f p r i n t f ( s t d e r r , " Node %d : Dst %d , f a i l e d l o c a l r e p a i r \ n " , index , r t > r t _ d s t ) ; #e n d i f } Packet : : f r e e ( ( Packet ) p ) ; } / / [ s c h e d u l i n g ] # i f d e f SA_CHANGE v o i d PingTimer : : handle ( Event ) { # i f d e f AODV_PING agent >sendPing ( ) ; double i n t e r v a l = PING_INTERVAL + 0 . 0 1 Random : : uniform ( ) ; a s s e r t ( i n t e r v a l >= 0 ) ; Sched ul er : : i n s t a n c e ( ) . s ched ul e ( t h i s , &i n t r , i n t e r v a l ) ; #e n d i f } #e n d i f / / [ s c h e d u l i n g ] end / B r o a d c a s t ID Management F u n c t i o n s / B r o a d c a s t I D AODV : : i d _ i n s e r t ( ns ad d r _ t id , u _ i n t 3 2 _ t b i d ) { B r o a d c a s t I D b = new B r o a d c a s t I D ( id , b i d ) ; assert (b ) ; b> e x p i r e = NOW + BCAST_ID_SAVE ; LIST_INSERT_HEAD (& bihead , b , l i n k ) ; return b ; } / SRD / B r o a d c a s t I D AODV : : i d _ l o o k u p ( ns ad d r _ t id , u _ i n t 3 2 _ t b i d ) { B r o a d c a s t I D b = bihead . l h _ f i r s t ; / / S e a r c h t h e l i s t f o r a match o f s o u r c e and b i d f o r ( ; b ; b = b> l i n k . l e _ n e x t ) { i f ( ( b> s r c == i d ) && ( b> i d == b i d ) ) return b ; } r e t u r n NULL ; } v o i d AODV : : i d _ p ur g e ( ) { B r o a d c a s t I D b = bihead . l h _ f i r s t ; B r o a d c a s t I D bn ; double now = NOW;

52

A.1. C++

f o r ( ; b ; b = bn ) { bn = b> l i n k . l e _ n e x t ; i f ( b>e x p i r e <= now ) { LIST_REMOVE ( b , l i n k ) ; delete b ; } } } / Helper Functions / double AODV : : PerHopTime ( a o d v _ r t _ e n t r y r t ) { i n t num_non_zero = 0 , i ; double t o t a l _ l a t e n c y = 0 . 0 ; if (! rt ) r e t u r n ( ( double ) NODE_TRAVERSAL_TIME ) ; f o r ( i =0; i < MAX_HISTORY ; i ++) { i f ( r t > r t _ d i s c _ l a t e n c y [ i ] > 0 . 0 ) { num_non_zero + + ; t o t a l _ l a t e n c y += r t > r t _ d i s c _ l a t e n c y [ i ] ; } } i f ( num_non_zero > 0) r e t u r n ( t o t a l _ l a t e n c y / ( double ) num_non_zero ) ; else r e t u r n ( ( double ) NODE_TRAVERSAL_TIME ) ; } / L i n k F a i l u r e Management F u n c t i o n s / s t a t i c v o i d a o d v _ r t _ f a i l e d _ c a l l b a c k ( Packet p , v o i d arg ) { ( ( AODV ) arg )> r t _ l l _ f a i l e d ( p ) ; } / T h i s r o u t i n e i s i n v o k e d when t h e l i n k l a y e r r e p o r t s a r o u t e f a i l e d . / v o i d AODV : : r t _ l l _ f a i l e d ( Packet p ) { s t r u c t hdr_cmn ch = HDR_CMN ( p ) ; s t r u c t h d r _ i p i h = HDR_IP ( p ) ; aodv_rt_entry r t ; ns ad d r _ t broken_nbr = ch>next_hop_ ; # i f n d e f AODV_LINK_LAYER_DETECTION drop ( p , DROP_RTR_MAC_CALLBACK ) ; #e l s e / Nondata p a c k e t s and B r o a d c a s t P a c k e t s can be dropped . / i f ( ! DATA_PACKET ( ch>ptype ( ) ) | | ( u _ i n t 3 2 _ t ) ih >daddr ( ) == IP_BROADCAST ) { drop ( p , DROP_RTR_MAC_CALLBACK ) ;

53

A.1. C++

return ; } log_link_broke (p ) ; i f ( ( r t = r t a b l e . r t _ l o o k u p ( ih >daddr ( ) ) ) == 0) { drop ( p , DROP_RTR_MAC_CALLBACK ) ; return ; } l o g _ l i n k _ d e l ( ch>next_hop_ ) ; # i f d e f AODV_LOCAL_REPAIR / i f t h e b r o k e n l i n k i s c l o s e r t o t h e d e s t than s o u r c e , attempt a l o c a l r e p a i r . O t h e r w i s e , b r i n g down t h e r o u t e . / i f ( ch>num_forwards ( ) > r t >r t _ ho p s ) { l o c al _r t _r e pa i r ( rt , p ) ; // l o c a l rep a i r // r e t r i e v e a l l the p a c kets i n the i f q using t h i s l i n k , / / queue t h e p a c k e t s f o r which l o c a l r e p a i r i s done , return ; } #e n d i f / / LOCAL REPAIR h a n d l e _ l i n k _ f a i l u r e ( broken_nbr ) ; # i f d e f AOMDV_PACKET_SALVAGING i f ( ! DATA_PACKET ( ch>ptype ( ) ) ) drop ( p , DROP_RTR_MAC_CALLBACK ) ; else { / / s a l v a g e t h e p a c k e t u s i n g an a l t e r n a t e path i f a v a i l a b l e . a o d v _ r t _ e n t r y r t = r t a b l e . r t _ l o o k u p ( ih >daddr ( ) ) ; i f ( r t && ( r t > r t _ f l a g s == RTF_UP ) && ( ch>aomdv_salvage_count_ < AOMDV_MAX_SALVAGE_COUNT) ) { ch>aomdv_salvage_count_ += 1 ; forward ( r t , p , NO_DELAY ) ; } e l s e drop ( p , DROP_RTR_MAC_CALLBACK ) ; } w hi l e ( ( p = ifqueue > f i l t e r ( broken_nbr ) ) ) { s t r u c t hdr_cmn ch = HDR_CMN ( p ) ; s t r u c t h d r _ i p i h = HDR_IP ( p ) ; i f ( ! DATA_PACKET ( ch>ptype ( ) ) ) drop ( p , DROP_RTR_MAC_CALLBACK ) ; else { / / s a l v a g e t h e p a c k e t u s i n g an a l t e r n a t e path i f a v a i l a b l e . a o d v _ r t _ e n t r y r t = r t a b l e . r t _ l o o k u p ( ih >daddr ( ) ) ; i f ( r t && ( r t > r t _ f l a g s == RTF_UP ) && ( ch>aomdv_salvage_count_ < AOMDV_MAX_SALVAGE_COUNT) ) { ch>aomdv_salvage_count_ += 1 ; forward ( r t , p , NO_DELAY ) ; } e l s e drop ( p , DROP_RTR_MAC_CALLBACK ) ; } } # e l s e / / NO PACKET SALVAGING drop ( p , DROP_RTR_MAC_CALLBACK ) ;

54

A.1. C++

/ / Do t h e same t h i n g f o r o t h e r p a c k e t s i n t h e i n t e r f a c e queue u s i n g t h e / / b r o k e n l i n k Mahesh w hi l e ( ( p = ifqueue > f i l t e r ( broken_nbr ) ) ) { drop ( p , DROP_RTR_MAC_CALLBACK ) ; } nb _ d el et e ( broken_nbr ) ; / MAYBE T H I S SHOULD NOT BE ? ? / #e n d i f / / NO PACKET SALVAGING

#e n d i f / / L I N K LAYER DETECTION } # i f n d e f AOMDV v o i d AODV : : h a n d l e _ l i n k _ f a i l u r e ( ns ad d r _ t i d ) { aodv_rt_entry rt , rtn ; Packet r e r r = Packet : : a l l o c ( ) ; s t r u c t h d r _ a o d v _ e r r o r r e = HDR_AODV_ERROR ( r e r r ) ; re >DestCount = 0 ; f o r ( r t = r t a b l e . head ( ) ; r t ; r t = r t n ) / / f o r each r t e n t r y { r t n = r t > r t _ l i n k . l e _ n e x t ; i f ( ( r t >r t _ ho p s ! = I N F I N I T Y 2 ) && ( r t >r t _ nex t ho p == i d ) ) { a s s e r t ( r t > r t _ f l a g s == RTF_UP ) ; a s s e r t ( ( r t >r t _ s eq no % 2 ) == 0 ) ; r t >r t _ s eq no + + ; re >unr eachab l e_ d s t [ re >DestCount ] = r t > r t _ d s t ; re >unr eachab l e_ d s t _ s eq no [ re >DestCount ] = r t >r t _ s eq no ; # i f d e f DEBUG f p r i n t f ( s t d e r r , "%s (% f ) : %d \ t (%d \ t%u \ t%d ) \ n " , __FUNCTION__ , NOW, index , re >unr eachab l e_ d s t [ re >DestCount ] , re >unr eachab l e_ d s t _ s eq no [ re >DestCount ] , r t >r t _ nex t ho p ) ; #e n d i f / / DEBUG re >DestCount += 1 ; rt_down ( r t ) ; } / / remove t h e l o s t n e i gh b o r from a l l t h e p r e c u r s o r l i s t s r t >p c _ d e l e t e ( i d ) ; } i f ( re >DestCount > 0) { # i f d e f DEBUG f p r i n t f ( s t d e r r , "%s (% f ) : %d \ t s end i ng RERR . . . \ n " , __FUNCTION__ , NOW, i nd ex ) ; #e n d i f / / DEBUG sendError ( rerr , f al s e ) ; } else { Packet : : f r e e ( r e r r ) ; } } v o i d AODV : : rt_down ( a o d v _ r t _ e n t r y r t ) { / Make s u r e t h a t you don t " down " a r o u t e more than once . / i f ( r t > r t _ f l a g s == RTF_DOWN) { return ; }

55

A.1. C++

r t >r t _ l a s t _ h o p _ c o u n t = r t >r t _ ho p s ; r t >r t _ ho p s = I N F I N I T Y 2 ; r t > r t _ f l a g s = RTF_DOWN ; r t >r t _ nex t ho p = 0 ; r t > r t _ e x p i r e = 0 ; } / rt_down f u n c t i o n / #e n d i f / /AOMDV v o i d AODV : : l o c a l _ r t _ r e p a i r ( a o d v _ r t _ e n t r y r t , Packet p ) { # i f d e f DEBUG f p r i n t f ( s t d e r r , "%s : Dst %d \ n " , __FUNCTION__ , r t > r t _ d s t ) ; #e n d i f // B u ffer the packet rqueue . enque ( p ) ; / / mark t h e r o u t e as under r e p a i r r t > r t _ f l a g s = RTF_IN_REPAIR ; sendRequest ( r t > r t _ d s t ) ; / / s e t up a t i m e r i n t e r r u p t Sched ul er : : i n s t a n c e ( ) . s ched ul e (& l r t i m e r , p>copy ( ) , r t >r t _ r e q _ t i m e o u t ) ; } / Route Handling F u n c t i o n s / v o i d AODV : : r t _ r e s o l v e ( Packet p ) { s t r u c t hdr_cmn ch = HDR_CMN ( p ) ; s t r u c t h d r _ i p i h = HDR_IP ( p ) ; aodv_rt_entry r t ; / S e t t h e t r a n s m i t f a i l u r e c a l l b a c k . That won t change . / ch> x m i t _ f a i l u r e _ = a o d v _ r t _ f a i l e d _ c a l l b a c k ; ch> x m i t _ f a i l u r e _ d a t a _ = ( v o i d ) t h i s ; r t = r t a b l e . r t _ l o o k u p ( ih >daddr ( ) ) ; i f ( r t == 0) { r t = r t a b l e . r t _ ad d ( ih >daddr ( ) ) ; } / I f t h e r o u t e i s up , f o r w a r d t h e p a c k e t / i f ( r t > r t _ f l a g s == RTF_UP ) { a s s e r t ( r t >r t _ ho p s ! = I N F I N I T Y 2 ) ; forward ( r t , p , NO_DELAY ) ; } / i f I am t h e s o u r c e o f t h e p a c k e t , then do a Route R e q u e s t . / e l s e i f ( ih >saddr ( ) == i nd ex ) { rqueue . enque ( p ) ; sendRequest ( r t > r t _ d s t ) ; } /

56

A.1. C++

A l o c a l r e p a i r i s i n p ro gres s . B u ffer the packet . / e l s e i f ( r t > r t _ f l a g s == RTF_IN_REPAIR ) { rqueue . enque ( p ) ; } / I am t r y i n g t o f o r w a r d a p a c k e t f o r someone e l s e t o which I don t have a r o u t e . / else { Packet r e r r = Packet : : a l l o c ( ) ; s t r u c t h d r _ a o d v _ e r r o r r e = HDR_AODV_ERROR ( r e r r ) ; / F o r now , drop t h e p a c k e t and send e r r o r upstream . Now t h e r o u t e e r r o r s a r e b r o a d c a s t t o upstream n e i g h b o r s Mahesh 0 9 / 1 1 / 9 9 / a s s e r t ( r t > r t _ f l a g s == RTF_DOWN ) ; re >DestCount = 0 ; re >unr eachab l e_ d s t [ re >DestCount ] = r t > r t _ d s t ; re >unr eachab l e_ d s t _ s eq no [ re >DestCount ] = r t >r t _ s eq no ; re >DestCount += 1 ; # i f d e f DEBUG f p r i n t f ( s t d e r r , "%s : sending RERR . . . \ n " , __FUNCTION__ ) ; #e n d i f sendError ( rerr , f al s e ) ; drop ( p , DROP_RTR_NO_ROUTE ) ; } } v o i d AODV : : r t _ p u r g e ( ) { aodv_rt_entry rt , rtn ; double now = NOW; double d e l a y = 0 . 0 ; Packet p ; f o r ( r t = r t a b l e . head ( ) ; r t ; r t = r t n ) { r t n = r t > r t _ l i n k . l e _ n e x t ; # i f n d e f AOMDV i f ( ( r t > r t _ f l a g s == RTF_UP ) && ( r t > r t _ e x p i r e < now ) ) { / / i f a v a l i d r o u t e has e x p i r e d , purge a l l p a c k e t s from / / send b u f f e r and i n v a l i d a t e t h e r o u t e . a s s e r t ( r t >r t _ ho p s ! = I N F I N I T Y 2 ) ; w hi l e ( ( p = rqueue . deque ( r t > r t _ d s t ) ) ) { # i f d e f DEBUG f p r i n t f ( s t d e r r , "%s : c a l l i n g drop ( ) \ n " , __FUNCTION__ ) ; #e n d i f / / DEBUG drop ( p , DROP_RTR_NO_ROUTE ) ; } r t >r t _ s eq no + + ; a s s e r t ( r t >r t _ s eq no % 2 ) ; rt_down ( r t ) ; } # e l s e / / AOMDV / / f o r each r t e n t r y

57

A.1. C++

/ / [ s c h e d u l i n g ] # i f n d e f SA_CHANGE i f ( r t > r t _ f l a g s == RTF_UP && ( r t > r t _ e x p i r e < now ) ) #e l s e / i f ( r t > r t _ f l a g s == RTF_UP && ( r t > r t _ e x p i r e < now ) ) we want t o remove a l l o l d paths , even i f t h e r t e n t r y i s not e x p i r e d ! / i f ( r t > r t _ f l a g s == RTF_UP ) #e n d i f / / [ s c h e d u l i n g ] end { / / [ s c h e d u l i n g ] # i f d e f SA_CHANGE / s t u p i d implementation , but e a s i e r l i k e t h i s / # i f d e f AODV_INFO AODV_Path path = r t > r t _ p a t h _ l i s t . l h _ f i r s t ; i n t num_path = r t >rt_num_paths_ ; f o r ( ; path ; path = path> p a t h _ l i n k . l e _ n e x t ) { i f ( path>e x p i r e < now ) { / p r i n t a l l t h e path t h a t w i l l be removed / num_path ; dumpPath ( r t , path , 1 , num_path ) ; } } #e n d i f #e n d i f / / [ s c h e d u l i n g ] end r t >path_purge ( ) ; i f ( r t >path_empty ( ) ) { w hi l e ( ( p = rqueue . deque ( r t > r t _ d s t ) ) ) { drop ( p , DROP_RTR_RTEXPIRE ) ; } r t >r t _ s eq no + + ; r t >r t _ s eq no = max ( r t >rt_seqno , r t >r t _ hi g hes t _ s eq n o _ h e a r d ) ; i f ( r t >r t _ s eq no % 2 == 0) r t >r t _ s eq no += 1 ; rt_down ( r t ) ; } } #e n d i f / / AOMDV

i f ( r t > r t _ f l a g s == RTF_UP ) { / / I f t h e r o u t e i s not e x p i r e d , / / and t h e r e a r e p a c k e t s i n t h e s e n d b u f f e r w a i t i n g , / / f o r w a r d them . T h i s s h o u l d not be needed , but t h i s e x t r a / / c h e c k does no harm . a s s e r t ( r t >r t _ ho p s ! = I N F I N I T Y 2 ) ; w hi l e ( ( p = rqueue . deque ( r t > r t _ d s t ) ) ) { forward ( r t , p , d e l a y ) ; d e l a y += ARP_DELAY ; } } e l s e i f ( rqueue . f i n d ( r t > r t _ d s t ) ) / / I f t h e r o u t e i s down and // i f there i s a packet fo r t h i s d es ti n a ti o n waiting in / / t h e s e n d b u f f e r , then send out r o u t e r e q u e s t . s e n d R e q u e s t / / w i l l c h e c k whether i t i s time t o r e a l l y send out r e q u e s t

58

A.1. C++

/ / o r not . / / T h i s may not be c r u c i a l t o do i t here , as each ge n e r a t e d / / p a c k e t w i l l do a s e n d R e q u e s t anyway . sendRequest ( r t > r t _ d s t ) ; } } / Packet Reception Routines / v o i d AODV : : r e c v ( Packet p , Handler ) { s t r u c t hdr_cmn ch = HDR_CMN ( p ) ; s t r u c t h d r _ i p i h = HDR_IP ( p ) ; assert ( i n i t i a l i z e d ( ) ) ; / / a s s e r t ( p>incoming == 0 ) ; / / XXXXX NOTE : use o f incoming f l a g has been d e p r a c a t e d ; I n o r d e r t o t r a c k / / d i r e c t i o n o f p k t flow , / / d i r e c t i o n _ i n hdr_cmn i s used i n s t e a d . s e e p a c k e t . h f o r d e t a i l s . i f ( ch>ptype ( ) == PT_AODV ) { ih > t t l _ = 1 ; recvAODV ( p ) ; return ; } / Must be a p a c k e t I m o r i g i n a t i n g . . . / i f ( ( ih >saddr ( ) == i nd ex ) && ( ch>num_forwards ( ) == 0 ) ) { / Add t h e I P Header / ch> s i z e ( ) += IP_HDR_LEN ; # i f d e f AOMDV ch>aomdv_salvage_count_ = 0 ; #e n d i f / / AOMDV / / Added by Parag Dadhania && John Novatnack t o handle b r o a d c a s t i n g i f ( ( u _ i n t 3 2 _ t ) ih >daddr ( ) ! = IP_BROADCAST ) ih > t t l _ = NETWORK_DIAMETER ; } / I rec ei ved a packet that I sent . Probably a routing loop . / e l s e i f ( ih >saddr ( ) == i nd ex ) { drop ( p , DROP_RTR_ROUTE_LOOP ) ; return ; } / P a c k e t I m f o r w a r d i n g . . . / else { / Check t h e TTL . I f i t i s z e r o , then d i s c a r d . / i f (ih > t t l _ == 0) { drop ( p , DROP_RTR_TTL ) ; return ; }

59

A.1. C++

} / / Added by Parag Dadhania && John Novatnack t o handle b r o a d c a s t i n g i f ( ( u _ i n t 3 2 _ t ) ih >daddr ( ) ! = IP_BROADCAST ) rt_resolve (p ) ; else forward ( ( a o d v _ r t _ e n t r y ) 0 , p , NO_DELAY ) ; }

v o i d AODV : : recvAODV ( Packet p ) { s t r u c t hdr_aodv ah = HDR_AODV ( p ) ; s t r u c t h d r _ i p i h = HDR_IP ( p ) ; a s s e r t ( ih >s p o r t ( ) == RT_PORT ) ; a s s e r t ( ih >d p o r t ( ) == RT_PORT ) ; / Incoming P a c k e t s . / s w i t ch ( ah>ah_type ) { cas e AODVTYPE_RREQ : r ecv R eq ues t ( p ) ; b r eak ; cas e AODVTYPE_RREP : recvReply (p ) ; b r eak ; cas e AODVTYPE_RERR : recvError (p ) ; b r eak ; cas e AODVTYPE_HELLO : recvHello (p ) ; b r eak ; / / [ s c h e d u l i n g ] # i f d e f SA_CHANGE # i f d e f AODV_PING cas e AODVTYPE_PING : recvPing ( p ) ; b r eak ; #e n d i f # i f d e f AODV_INFO cas e AODVTYPE_INFO : Packet : : f r e e ( p ) ; / / not needed b r eak ; #e n d i f #e n d i f / / [ s c h e d u l i n g ] end default : f p r i n t f ( s t d e r r , " I n v a l i d AODV t y p e (% x ) \ n " , ah>ah_type ) ; exit ( 1 ) ; } } # i f n d e f AOMDV v o i d AODV : : r ecv R eq ues t ( Packet p ) { s t r u c t h d r _ i p i h = HDR_IP ( p ) ; s t r u c t hd r _ ao d v _ r eq ues t rq = HDR_AODV_REQUEST ( p ) ;

60

A.1. C++

aodv_rt_entry r t ; / Drop i f : I m t h e s o u r c e I r e c e n t l y heard t h i s r e q u e s t . / i f ( rq> r q _ s r c == i nd ex ) { # i f d e f DEBUG f p r i n t f ( s t d e r r , "%s : got my own REQUEST\ n " , __FUNCTION__ ) ; #e n d i f / / DEBUG Packet : : f r e e ( p ) ; return ; } i f ( i d _ l o o k u p ( rq >r q _ s r c , rq >r q _ b c a s t _ i d ) ) { # i f d e f DEBUG f p r i n t f ( s t d e r r , "%s : d i s c a r d i n g r eq ues t \ n " , __FUNCTION__ ) ; #e n d i f / / DEBUG Packet : : f r e e ( p ) ; return ; } / Cache t h e b r o a d c a s t ID / i d _ i n s e r t ( rq >r q _ s r c , rq >r q _ b c a s t _ i d ) ;

/ We a r e e i t h e r going t o f o r w a r d t h e REQUEST o r g e n e r a t e a REPLY . B e f o r e we do anything , we make s u r e t h a t t h e REVERSE route i s i n the route ta b l e . / aodv_rt_entry rt0 ; // rt0 i s the r e v e r s e route r t 0 = r t a b l e . r t _ l o o k u p ( rq> r q _ s r c ) ; i f ( r t 0 == 0) / i f not i n t h e r o u t e t a b l e / { / / c r e a t e an e n t r y f o r t h e r e v e r s e r o u t e . r t 0 = r t a b l e . r t _ ad d ( rq > r q _ s r c ) ; } rt0 > r t _ e x p i r e = max ( rt0 >r t _ e x p i r e , (NOW + REV_ROUTE_LIFE ) ) ; i f ( ( rq >r q _ s r c_ s eq no > rt0 >r t _ s eq no ) | | ( ( rq >r q _ s r c_ s eq no == rt0 >r t _ s eq no ) && ( rq >rq_hop_count < rt0 >r t _ ho p s ) ) ) { / / I f we have a f r e s h e r s e q no . o r l e s s e r #hops f o r t h e / / same s e q no . , update t h e r t e n t r y . E l s e don t b o t h e r . / / CHANGE ( make s u r e we i n c r e m e n t hop count b e f o r e adding r e v e r s e path // route entry . r t _ up d at e ( rt0 , rq >r q _ s r c_ s eq no , rq >rq_hop_count + 1 , ih >saddr ( ) , max ( rt0 > r t _ e x p i r e , (NOW + REV_ROUTE_LIFE ) ) ) ; i f ( rt0 >r t _ r e q _ t i m e o u t > 0 . 0 ) { / / R e s e t t h e s o f t s t a t e and / / S e t e x p i r y time t o NOW + ACTIVE_ROUTE_TIMEOUT

61

A.1. C++

/ / T h i s i s b e c a u s e r o u t e i s used i n t h e f o r w a r d d i r e c t i o n , / / but o n l y s o u r c e s ge t b e n e f i t e d by t h i s change rt0 > r t _ r e q _ c n t = 0 ; rt0 >r t _ r e q _ t i m e o u t = 0 . 0 ; rt0 > r t _ r e q _ l a s t _ t t l = rq >rq_hop_count ; rt0 > r t _ e x p i r e = NOW + ACTIVE_ROUTE_TIMEOUT ; } / F i n d out whether any b u f f e r e d p a c k e t can b e n e f i t from t h e revers e route . May need some change i n t h e f o l l o w i n g code Mahesh 0 9 / 1 1 / 9 9 / a s s e r t ( rt0 > r t _ f l a g s == RTF_UP ) ; Packet b u f f e r e d _ p k t ; w hi l e ( ( b u f f e r e d _ p k t = rqueue . deque ( rt0 > r t _ d s t ) ) ) { i f ( r t 0 && ( rt0 > r t _ f l a g s == RTF_UP ) ) { a s s e r t ( rt0 >r t _ ho p s ! = I N F I N I T Y 2 ) ; forward ( rt0 , b uf f er ed _ p kt , NO_DELAY ) ; } } } / / End f o r p u t t i n g r e v e r s e r o u t e i n r t t a b l e

/ We have t a k e n c a r e o f t h e r e v e r s e r o u t e s t u f f . Now s e e whether we can send a r o u t e r e p l y . / r t = r t a b l e . r t _ l o o k u p ( rq >r q _ d s t ) ; / / F i r s t c h e c k i f I am t h e d e s t i n a t i o n . . i f ( rq >r q _ d s t == i nd ex ) { # i f d e f DEBUG f p r i n t f ( s t d e r r , "%d %s : d e s t i n a t i o n sending r e p l y \ n " , index , __FUNCTION__ ) ; #e n d i f / / DEBUG

/ / J u s t t o be s a f e , I use t h e max . Somebody may have / / i n c r e m e n t e d t h e d s t seqno . seqno = max ( seqno , rq >r q _ d s t _ s eq no ) + 1 ; i f ( seqno % 2 ) seqno + + ; s end R ep l y ( rq >r q _ s r c , 1, index , seqno , MY_ROUTE_TIMEOUT , rq >rq_timestamp ) ; Packet : : f r e e ( p ) ; } / / I am not t h e d e s t i n a t i o n , but I may have a f r e s h enough r o u t e . e l s e i f ( r t && ( r t >r t _ ho p s ! = I N F I N I T Y 2 ) && ( r t >r t _ s eq no >= rq >r q _ d s t _ s eq no ) ) { / / a s s e r t ( r t > r t _ f l a g s == RTF_UP ) ; a s s e r t ( rq >r q _ d s t == r t > r t _ d s t ) ; / / a s s e r t ( ( r t >r t _ s e q n o % 2 ) == 0 ) ; / / i s t h e seqno even ? // // // // // // IP Destination Hop Count Dest I P Address D e s t Sequence Num Lifetime timestamp

62

A.1. C++

s end R ep l y ( rq>r q _ s r c , r t >r t _ ho p s + 1 , rq >r q _ d s t , r t >rt_seqno , ( u _ i n t 3 2 _ t ) ( r t > r t _ e x p i r e NOW) , rq >rq_timestamp ) ; / / I n s e r t nexthops t o RREQ s o u r c e and RREQ d e s t i n a t i o n i n t h e / / p r e c u r s o r l i s t s o f d e s t i n a t i o n and s o u r c e r e s p e c t i v e l y r t > p c _ i n s e r t ( rt0 >r t _ nex t ho p ) ; / / nexthop t o RREQ s o u r c e rt0 > p c _ i n s e r t ( r t >r t _ nex t ho p ) ; / / nexthop t o RREQ d e s t i n a t i o n # i f d e f RREQ_GRAT_RREP s end R ep l y ( rq>r q _ d s t , rq >rq_hop_count , rq >r q _ s r c , rq >r q _ s r c_ s eq no , ( u _ i n t 3 2 _ t ) ( r t > r t _ e x p i r e NOW) , rq >rq_timestamp ) ; #e n d i f / / TODO : send g r a t RREP t o d s t i f G f l a g s e t i n RREQ / / u s i n g rq >r q _ s r c _ s e q n o , rq >rq_hop_counT / / DONE : I n c l u d e d g r a t u i t o u s r e p l i e s t o be s e n t as p e r I E T F aodv d r a f t / / s p e c i f i c a t i o n . As o f now , G f l a g has not been d y n a m i c a l l y used / / and i s always s e t o r r e s e t i n aodvp a c k e t . h , Anant U t g i k a r , 0 9 / 1 6 / 0 2 . Packet : : f r e e ( p ) ; } / Can t r e p l y . So f o r w a r d t h e Route R e q u e s t / else { ih >saddr ( ) = i nd ex ; ih >daddr ( ) = IP_BROADCAST ; rq >rq_hop_count += 1 ; / / Maximum s e q u e n c e number s e e n en r o u t e i f ( r t ) rq >r q _ d s t _ s eq no = max ( r t >rt_seqno , rq >r q _ d s t _ s eq no ) ; forward ( ( a o d v _ r t _ e n t r y ) 0 , p , DELAY ) ; } } v o i d AODV : : s end R ep l y ( ns ad d r _ t i p d s t , u _ i n t 3 2 _ t hop_count , ns ad d r _ t r p d s t , u _ i n t 3 2 _ t rpseq , u _ i n t 3 2 _ t l i f e t i m e , double timestamp ) { Packet p = Packet : : a l l o c ( ) ; s t r u c t hdr_cmn ch = HDR_CMN ( p ) ; s t r u c t h d r _ i p i h = HDR_IP ( p ) ; s t r u c t hd r _ ao d v _ r ep l y rp = HDR_AODV_REPLY( p ) ; aodv_rt_entry r t = r t ab l e . rt_lookup ( ipdst ) ; # i f d e f DEBUG f p r i n t f ( s t d e r r , " sending R ep l y from %d at %.2 f \ n " , index , NOW ) ; #e n d i f / / DEBUG assert ( r t ) ; rp >r p _ t y p e = AODVTYPE_RREP ; rp >rp_hop_count = hop_count ; rp >r p _ d s t = r p d s t ; rp >r p _ d s t _ s eq no = r p s eq ; rp > r p _ s r c = i nd ex ; rp > r p _ l i f e t i m e = l i f e t i m e ; rp >rp_timestamp = timestamp ;

63

A.1. C++

ch>ptype ( ) = PT_AODV ; ch> s i z e ( ) = IP_HDR_LEN + rp> s i z e ( ) ; ch> i f a c e ( ) = 2; ch> e r r o r ( ) = 0 ; ch>ad d r _ t y p e ( ) = NS_AF_INET ; ch>next_hop_ = r t >r t _ nex t ho p ; ch>prev_hop_ = i nd ex ; / / AODV hack ch> d i r e c t i o n ( ) = hdr_cmn : : DOWN; ih >saddr ( ) = i nd ex ; ih >daddr ( ) = i p d s t ; ih >s p o r t ( ) = RT_PORT ; ih >d p o r t ( ) = RT_PORT ; ih > t t l _ = NETWORK_DIAMETER ; Sched ul er : : i n s t a n c e ( ) . s ched ul e ( t a r g e t _ , p , 0 . ) ; } v o i d AODV : : r e c v R e p l y ( Packet p ) { / / s t r u c t hdr_cmn ch = HDR_CMN ( p ) ; s t r u c t h d r _ i p i h = HDR_IP ( p ) ; s t r u c t hd r _ ao d v _ r ep l y rp = HDR_AODV_REPLY( p ) ; aodv_rt_entry r t ; char s u p p r e s s _ r e p l y = 0 ; double d e l a y = 0 . 0 ; # i f d e f DEBUG f p r i n t f ( s t d e r r , "%d %s : r e c e i v e d a REPLY \ n " , index , __FUNCTION__ ) ; #e n d i f / / DEBUG

/ Got a r e p l y . So r e s e t t h e " s o f t s t a t e " maintained f o r r o u t e r e q u e s t s i n t h e r e q u e s t t a b l e . We don t r e a l l y have have a s e p a r a t e r e q u e s t t a b l e . I t i s j u s t a p a r t o f t h e routing table i t s e l f . / / / Note t h a t r p _ d s t i s t h e d e s t o f t h e data p a c k e t s , not t h e / / t h e d e s t o f t h e r e p l y , which i s t h e s r c o f t h e data p a c k e t s . r t = r t a b l e . r t _ l o o k u p ( rp >r p _ d s t ) ; / I f I don t have a r t e n t r y t o t h i s h o s t . . . adding / i f ( r t == 0) { r t = r t a b l e . r t _ ad d ( rp >r p _ d s t ) ; } / Add a f o r w a r d r o u t e t a b l e e n t r y . . . h e r e I am f o l l o w i n g P e r k i n s R o y e r AODV paper almost l i t e r a l l y SRD 5/99 / i f ( ( r t >r t _ s eq no < rp >r p _ d s t _ s eq no ) | | / / newer r o u t e ( ( r t >r t _ s eq no == rp >r p _ d s t _ s eq no ) && ( r t >r t _ ho p s > rp>rp_hop_count ) ) ) // s h o r t e r or b e t t e r route { / / Update t h e r t e n t r y r t _ up d at e ( r t , rp >rp_dst_seqno , rp >rp_hop_count , rp >r p _ s r c , NOW + rp > r p _ l i f e t i m e ) ; // r e s e t the s o f t s t a t e r t >r t _ r e q _ c n t = 0 ;

64

A.1. C++

r t >r t _ r e q _ t i m e o u t = 0 . 0 ; r t > r t _ r e q _ l a s t _ t t l = rp >rp_hop_count ; i f ( ih >daddr ( ) == i nd ex ) / / I f I am t h e o r i g i n a l s o u r c e { / / Update t h e r o u t e d i s c o v e r y l a t e n c y s t a t i s t i c s / / rp >rp_timestamp i s t h e time o f r e q u e s t o r i g i n a t i o n r t > r t _ d i s c _ l a t e n c y [ r t >h i s t _ i n d x ] = (NOW rp >rp_timestamp ) / ( double ) rp >rp_hop_count ; / / i n c r e m e n t i n d x f o r n e x t time r t >h i s t _ i n d x = ( r t > h i s t _ i n d x + 1 ) % MAX_HISTORY ; } / Send a l l p a c k e t s queued i n t h e s e n d b u f f e r d e s t i n e d f o r this destination . XXX o b s e r v e t h e " s e c o n d " use o f p . / Packet b uf _ p kt ; w hi l e ( ( b uf _ p kt = rqueue . deque ( r t > r t _ d s t ) ) ) { i f ( r t >r t _ ho p s ! = I N F I N I T Y 2 ) { a s s e r t ( r t > r t _ f l a g s == RTF_UP ) ; / / D e l a y them a l i t t l e t o h e l p ARP . O t h e r w i s e ARP / / may drop p a c k e t s . SRD 5 / 23/ 9 9 forward ( r t , buf_pkt , d e l a y ) ; d e l a y += ARP_DELAY ; } } } else { suppress_reply = 1 ; } / I f r e p l y i s f o r me , d i s c a r d i t . / i f ( ih >daddr ( ) == i nd ex | | s u p p r e s s _ r e p l y ) { Packet : : f r e e ( p ) ; } / O t h e r w i s e , f o r w a r d t h e Route R e p l y . / else { // Find the r t en try a o d v _ r t _ e n t r y r t 0 = r t a b l e . r t _ l o o k u p ( ih >daddr ( ) ) ; / / I f t h e r t i s up , f o r w a r d i f ( r t 0 && ( rt0 >r t _ ho p s ! = I N F I N I T Y 2 ) ) { a s s e r t ( rt0 > r t _ f l a g s == RTF_UP ) ; rp >rp_hop_count += 1 ; rp > r p _ s r c = i nd ex ; forward ( rt0 , p , NO_DELAY ) ; / / I n s e r t t h e nexthop towards t h e RREQ s o u r c e t o / / t h e p r e c u r s o r l i s t o f t h e RREQ d e s t i n a t i o n r t > p c _ i n s e r t ( rt0 >r t _ nex t ho p ) ; / / nexthop t o RREQ s o u r c e } else { / / I don t know how t o f o r w a r d . . drop t h e r e p l y .

65

A.1. C++

# i f d e f DEBUG f p r i n t f ( s t d e r r , "%s : dropping Route R ep l y \ n " , __FUNCTION__ ) ; #e n d i f / / DEBUG drop ( p , DROP_RTR_NO_ROUTE ) ; } } } v o i d AODV : : r t _ up d at e ( a o d v _ r t _ e n t r y r t , u _ i n t 3 2 _ t seqnum , u _ i n t 1 6 _ t m et r i c , ns ad d r _ t nexthop , double e x p i r e _ t i m e ) { r t >r t _ s eq no = seqnum ; r t >r t _ ho p s = m et r i c ; r t > r t _ f l a g s = RTF_UP ; r t >r t _ nex t ho p = nexthop ; r t > r t _ e x p i r e = e x p i r e _ t i m e ; } #e n d i f / /AOMDV # i f n d e f AOMDV v o i d AODV : : r e c v E r r o r ( Packet p ) { s t r u c t h d r _ i p i h = HDR_IP ( p ) ; s t r u c t h d r _ a o d v _ e r r o r r e = HDR_AODV_ERROR ( p ) ; aodv_rt_entry r t ; u_int8_t i ; Packet r e r r = Packet : : a l l o c ( ) ; s t r u c t h d r _ a o d v _ e r r o r nre = HDR_AODV_ERROR ( r e r r ) ; nre>DestCount = 0 ; f o r ( i =0; i < re >DestCount ; i ++) { / / F o r each u n r e a c h a b l e d e s t i n a t i o n r t = r t a b l e . r t _ l o o k u p ( re >unr eachab l e_ d s t [ i ] ) ; i f ( r t && ( r t >r t _ ho p s ! = I N F I N I T Y 2 ) && ( r t >r t _ nex t ho p == ih >saddr ( ) ) && ( r t >r t _ s eq no <= re >unr eachab l e_ d s t _ s eq no [ i ] ) ) { a s s e r t ( r t > r t _ f l a g s == RTF_UP ) ; a s s e r t ( ( r t >r t _ s eq no % 2 ) == 0 ) ; / / i s t h e seqno even ? # i f d e f DEBUG f p r i n t f ( s t d e r r , "%s (% f ) : %d \ t (%d \ t%u \ t%d ) \ t (%d \ t%u \ t%d ) \ n " , __FUNCTION__ ,NOW, index , r t >r t _ d s t , r t >rt_seqno , r t >rt_nexthop , re >unr eachab l e_ d s t [ i ] , re >unr eachab l e_ d s t _ s eq no [ i ] , ih >saddr ( ) ) ; #e n d i f / / DEBUG r t >r t _ s eq no = re >unr eachab l e_ d s t _ s eq no [ i ] ; rt_down ( r t ) ; / / Not s u r e whether t h i s i s t h e r i g h t t h i n g t o do Packet p kt ; w hi l e ( ( p kt = ifqueue > f i l t e r ( ih >saddr ( ) ) ) ) { drop ( pkt , DROP_RTR_MAC_CALLBACK ) ; } / / i f p r e c u r s o r l i s t nonempty add t o RERR and d e l e t e t h e // precursor l i s t i f ( ! r t >pc_empty ( ) ) { nre>unr eachab l e _ d s t [ nre>DestCount ] = r t > r t _ d s t ; nre>unr eachab l e_ d s t _ s eq no [ nre>DestCount ] = r t >r t _ s eq no ; nre>DestCount += 1 ; r t >p c _ d e l e t e ( ) ; }

66

A.1. C++

} } i f ( nre >DestCount > 0) { # i f d e f DEBUG f p r i n t f ( s t d e r r , "%s (% f ) : %d \ t sending RERR . . . \ n " , __FUNCTION__ , NOW, i nd ex ) ; #e n d i f / / DEBUG sendError ( r e r r ) ; } else { Packet : : f r e e ( r e r r ) ; } Packet : : f r e e ( p ) ; } #e n d i f / /AOMDV / Packet Transmission Routines / v o i d AODV : : forward ( a o d v _ r t _ e n t r y r t , Packet p , double d e l a y ) { s t r u c t hdr_cmn ch = HDR_CMN ( p ) ; s t r u c t h d r _ i p i h = HDR_IP ( p ) ; i f ( ih > t t l _ == 0) { # i f d e f DEBUG f p r i n t f ( s t d e r r , "%s : c a l l i n g drop ( ) \ n " , __PRETTY_FUNCTION__ ) ; #e n d i f / / DEBUG drop ( p , DROP_RTR_TTL ) ; return ; } if ( rt ) { a s s e r t ( r t > r t _ f l a g s == RTF_UP ) ; ch>ad d r _ t y p e ( ) = NS_AF_INET ; # i f n d e f AOMDV ch>next_hop ( ) = r t >r t _ nex t ho p ; r t > r t _ e x p i r e = NOW + ACTIVE_ROUTE_TIMEOUT ; / / CHANGE i f ( ( ih >saddr ( ) ! = i nd ex ) && DATA_PACKET ( ch>ptype ( ) ) ) r t > r t _ e r r o r = t r u e ; / / CHANGE # e l s e / /AOMDV / / [ s c h e d u l i n g ] changed argument # i f d e f SA_CHANGE AODV_Path path = r t >p a t h _ f i n d ( ih >saddr ( ) , i nd ex ) ; #else AODV_Path path = r t >p a t h _ f i n d ( ) ; #e n d i f / / [ s c h e d u l i n g ] # i f d e f SA_CHANGE i f ( ih >saddr ( ) == i nd ex ) { r t > t x _ r x _ i d = ih >daddr ( ) ; / / t h i s node i s a s e n d e r / / as we assume t o have o n l y one o u t go i n g c o n n e c t i o n t h i s works , // otherwise a l i s t of d e s t i n a t i o n s i s required } #e n d i f / / [ s c h e d u l i n g ] end

67

A.1. C++

ch>next_hop ( ) = path>nexthop ; path> e x p i r e = NOW + ACTIVE_ROUTE_TIMEOUT ; / / CHANGE i f ( ( ih >saddr ( ) ! = i nd ex ) && DATA_PACKET ( ch>ptype ( ) ) ) { r t > r t _ e r r o r = t r u e ; } / / CHANGE #e n d i f / /AOMDV / / i m p o r t a n t : change t h e p a c k e t s d i r e c t i o n ch> d i r e c t i o n ( ) = hdr_cmn : : DOWN; } else { // i f i t i s a broadcast packet

a s s e r t ( ih >daddr ( ) == ( ns ad d r _ t ) IP_BROADCAST ) ; ch>ad d r _ t y p e ( ) = NS_AF_NONE ; / / i m p o r t a n t : change t h e p a c k e t s d i r e c t i o n ch> d i r e c t i o n ( ) = hdr_cmn : : DOWN; } // I f i t i s a broadcast packet i f ( ih >daddr ( ) == ( ns ad d r _ t ) IP_BROADCAST ) { a s s e r t ( r t == 0 ) ; / J i t t e r t h e s e n d i n g o f b r o a d c a s t p a c k e t s by 10ms / Sched ul er : : i n s t a n c e ( ) . s ched ul e ( t a r g e t _ , p , 0 . 0 1 Random : : uniform ( ) ) ; } / / Not a b r o a d c a s t p a c k e t else { i f ( delay > 0.0) { Sched ul er : : i n s t a n c e ( ) . s ched ul e ( t a r g e t _ , p , d e l a y ) ; } else { / / Not a b r o a d c a s t p a c k e t , no d e l a y , send i m m e d i a t e l y Sched ul er : : i n s t a n c e ( ) . s ched ul e ( t a r g e t _ , p , 0 . ) ; } } } / / CHANGE v o i d AODV : : f o r w ar d R ep l y ( a o d v _ r t _ e n t r y r t , Packet p , double d e l a y ) { s t r u c t hdr_cmn ch = HDR_CMN ( p ) ; s t r u c t h d r _ i p i h = HDR_IP ( p ) ; i f ( ih > t t l _ == 0) { # i f d e f DEBUG f p r i n t f ( s t d e r r , "%s : c a l l i n g drop ( ) \ n " , __PRETTY_FUNCTION__ ) ; #e n d i f / / DEBUG drop ( p , DROP_RTR_TTL ) ; return ; } if ( rt ) {

68

A.1. C++

a s s e r t ( r t > r t _ f l a g s == RTF_UP ) ; ch>ad d r _ t y p e ( ) = NS_AF_INET ; # i f n d e f AOMDV ch>next_hop ( ) = r t >r t _ nex t ho p ; r t > r t _ e x p i r e = NOW + ACTIVE_ROUTE_TIMEOUT ; / / CHANGE i f ( ( ih >saddr ( ) ! = i nd ex ) && DATA_PACKET ( ch>ptype ( ) ) ) r t > r t _ e r r o r = t r u e ; / / CHANGE # e l s e / /AOMDV / / CHANGE i f ( ( ih >saddr ( ) ! = i nd ex ) && DATA_PACKET ( ch>ptype ( ) ) ) { r t > r t _ e r r o r = t r u e ; } / / CHANGE #e n d i f / /AOMDV ch> d i r e c t i o n ( ) = hdr_cmn : : DOWN; / / i m p o r t a n t : change t h e p a c k e t s d i r e c t i o n } else { // i f i t i s a broadcast packet a s s e r t ( ih >daddr ( ) == ( ns ad d r _ t ) IP_BROADCAST ) ; ch>ad d r _ t y p e ( ) = NS_AF_NONE ; ch> d i r e c t i o n ( ) = hdr_cmn : : DOWN; / / i m p o r t a n t : change t h e p a c k e t s d i r e c t i o n } i f ( ih >daddr ( ) == ( ns ad d r _ t ) IP_BROADCAST ) { // I f i t i s a broadcast packet a s s e r t ( r t == 0 ) ; / J i t t e r t h e s e n d i n g o f b r o a d c a s t p a c k e t s by 10ms / Sched ul er : : i n s t a n c e ( ) . s ched ul e ( t a r g e t _ , p , 0 . 0 1 Random : : uniform ( ) ) ; } e l s e / / Not a b r o a d c a s t p a c k e t { i f ( delay > 0.0) { Sched ul e r : : i n s t a n c e ( ) . s ched ul e ( t a r g e t _ , p , d e l a y ) ; } else { / / Not a b r o a d c a s t p a c k e t , no d e l a y , send i m m e d i a t e l y Sched ul e r : : i n s t a n c e ( ) . s ched ul e ( t a r g e t _ , p , 0 . ) ; } } } / / CHANGE v o i d AODV : : sendRequest ( ns ad d r _ t d s t ) { / / A l l o c a t e a RREQ p a c k e t Packet p = Packet : : a l l o c ( ) ; s t r u c t hdr_cmn ch = HDR_CMN ( p ) ; s t r u c t h d r _ i p i h = HDR_IP ( p ) ; s t r u c t hd r _ ao d v _ r eq ues t rq = HDR_AODV_REQUEST ( p ) ; aodv_rt_entry r t = r t a b l e . rt_lookup ( dst ) ; assert ( r t ) ;

69

A.1. C++

/ R a t e l i m i t s e n d i n g o f Route R e q u e s t s . We a r e v e r y c o n s e r v a t i v e about s e n d i n g out r o u t e r e q u e s t s . / i f ( r t > r t _ f l a g s == RTF_UP ) { a s s e r t ( r t >r t _ ho p s ! = I N F I N I T Y 2 ) ; Packet : : f r e e ( ( Packet ) p ) ; return ; } i f ( r t >r t _ r e q _ t i m e o u t > NOW) { Packet : : f r e e ( ( Packet ) p ) ; return ; } / / r t _ r e q _ c n t i s t h e no . o f t i m e s we d i d networkwide b r o a d c a s t / / RREQ_RETRIES i s t h e maximum number we w i l l a l l o w b e f o r e / / going t o a l o n g t i m e o u t . i f ( r t >r t _ r e q _ c n t > RREQ_RETRIES ) { r t >r t _ r e q _ t i m e o u t = NOW + MAX_RREQ_TIMEOUT ; r t >r t _ r e q _ c n t = 0 ; Packet b uf _ p kt ; w hi l e ( ( b uf _ p kt = rqueue . deque ( r t > r t _ d s t ) ) ) { drop ( buf_pkt , DROP_RTR_NO_ROUTE ) ; } Packet : : f r e e ( ( Packet ) p ) ; return ; } # i f d e f DEBUG f p r i n t f ( s t d e r r , " (%2d ) %2d sending Route Request , d s t : %d \ n " , ++ r o ut e_ r eq ues t , index , r t > r t _ d s t ) ; #e n d i f / / DEBUG / / Determine t h e TTL t o be used t h i s time . / / Dynamic TTL e v a l u a t i o n SRD r t > r t _ r e q _ l a s t _ t t l = max ( r t > r t _ r e q _ l a s t _ t t l , r t >r t _ l a s t _ h o p _ c o u n t ) ; i f (0 == r t > r t _ r e q _ l a s t _ t t l ) { / / f i r s t time q u e r y b r o a d c a s t ih > t t l _ = TTL_START ; } else { / / Expanding r i n g s e a r c h . i f ( r t > r t _ r e q _ l a s t _ t t l < TTL_THRESHOLD) ih > t t l _ = r t > r t _ r e q _ l a s t _ t t l + TTL_INCREMENT ; else { / / networkwide b r o a d c a s t ih > t t l _ = NETWORK_DIAMETER ; r t > r t _ r e q _ c n t += 1 ; } } / / remember t h e TTL used f o r t h e n e x t time r t > r t _ r e q _ l a s t _ t t l = ih > t t l _ ; / / PerHopTime i s t h e r o u n d t r i p time p e r hop f o r r o u t e r e q u e s t s .

70

A.1. C++

/ / The f a c t o r 2 . 0 i s j u s t t o be s a f e . . SRD 5 / 22/ 9 9 / / A l s o note t h a t we a r e making t i m e o u t s t o be l a r g e r i f we have / / done network wide b r o a d c a s t b e f o r e . r t >r t _ r e q _ t i m e o u t = 2 . 0 ( double ) ih > t t l _ PerHopTime ( r t ) ; i f ( r t > r t _ r e q _ c n t > 0) r t >r t _ r e q _ t i m e o u t = r t > r t _ r e q _ c n t ; r t >r t _ r e q _ t i m e o u t += NOW; / / Don t l e t t h e t i m e o u t t o be i f ( r t >r t _ r e q _ t i m e o u t > NOW + r t >r t _ r e q _ t i m e o u t = NOW + r t > r t _ e x p i r e = 0 ; // i n i t too l a r g e , however . . SRD 6/8/99 MAX_RREQ_TIMEOUT ) MAX_RREQ_TIMEOUT ; v a l u e ? RG

# i f d e f DEBUG f p r i n t f ( s t d e r r , " (%2d ) %2d sending Route Request , d s t : %d , t o ut %f ms\ n " , ++ r o ut e_ r eq ues t , index , r t >r t _ d s t , r t >r t _ r e q _ t i m e o u t NOW) ; #e n d i f / / DEBUG

/ / F i l l out t h e RREQ p a c k e t ch>ptype ( ) = PT_AODV ; ch> s i z e ( ) = IP_HDR_LEN + rq > s i z e ( ) ; ch> i f a c e ( ) = 2; ch> e r r o r ( ) = 0 ; ch>ad d r _ t y p e ( ) = NS_AF_NONE ; ch>prev_hop_ = i nd ex ; / / AODV hack ih >saddr ( ) ih >daddr ( ) ih >s p o r t ( ) ih >d p o r t ( ) = = = = i nd ex ; IP_BROADCAST ; RT_PORT ; RT_PORT ;

/ / F i l l up some more f i e l d s . rq >r q _ t y p e = AODVTYPE_RREQ ; rq >rq_hop_count = 0 ; / / CHANGE ( p r e v i o u s l y 1 ) rq >r q _ b c a s t _ i d = b i d + + ; rq >r q _ d s t = d s t ; rq >r q _ d s t _ s eq no = ( r t ? r t >r t _ s eq no : 0 ) ; rq > r q _ s r c = i nd ex ; seqno += 2 ; a s s e r t ( ( seqno % 2 ) == 0 ) ; rq >r q _ s r c_ s eq no = seqno ; rq >rq_timestamp = NOW; Sched ul er : : i n s t a n c e ( ) . s ched ul e ( t a r g e t _ , p , 0 . ) ; } v o i d AODV : : s e n d E r r o r ( Packet p , b o o l j i t t e r ) { s t r u c t hdr_cmn ch = HDR_CMN ( p ) ; s t r u c t h d r _ i p i h = HDR_IP ( p ) ; s t r u c t h d r _ a o d v _ e r r o r r e = HDR_AODV_ERROR ( p ) ; # i f d e f ERROR f p r i n t f ( s t d e r r , " sending E r r o r from %d at %.2 f \ n " , index , NOW ) ; #e n d i f / / DEBUG re >r e _ t y p e = AODVTYPE_RERR ; / / DestCount and l i s t o f u n r e a c h a b l e d e s t i n a t i o n s a r e a l r e a d y f i l l e d ch>ptype ( ) ch> s i z e ( ) ch> i f a c e ( ) ch> e r r o r ( ) ch>ad d r _ t y p e ( ) = = = = = PT_AODV ; IP_HDR_LEN + re > s i z e ( ) ; 2; 0; NS_AF_NONE ;

71

A.1. C++

ch>next_hop_ = 0; ch>prev_hop_ = i nd ex ; ch> d i r e c t i o n ( ) = hdr_cmn : : DOWN; ih >saddr ( ) ih >daddr ( ) ih >s p o r t ( ) ih >d p o r t ( ) ih > t t l _ = = = = = i nd ex ; IP_BROADCAST ; RT_PORT ; RT_PORT ; 1;

/ / AODV hack / / i m p o r t a n t : change t h e p a c k e t s d i r e c t i o n

/ / Do we need any j i t t e r ? Y e s if ( jitter ) Sched ul er : : i n s t a n c e ( ) . s ched ul e ( t a r g e t _ , p , 0 . 0 1 Random : : uniform ( ) ) ; else Sched ul er : : i n s t a n c e ( ) . s ched ul e ( t a r g e t _ , p , 0 . 0 ) ; } / / [ s c h e d u l i n g ] # i f d e f SA_CHANGE # i f d e f AODV_PING v o i d AODV : : sendPing ( ) { // ping a l l the d e s t i n a t i o n s vi a a l l paths aodv_rt_entry rt , rtn ; double d e l a y ; / / run through t h e r o u t i n g t a b l e and c r e a t e a p i n g f o r a l l p a t h s / / f o r each r t e n t r y f o r ( r t = r t a b l e . head ( ) ; r t ; r t = r t n ) { / / c h e c k i f r o u t e i s up and c h e c k t h e d e s t i f ( r t > r t _ f l a g s == RTF_UP && r t > r t _ d s t == r t > t x _ r x _ i d ) { AODV_Path path = r t > r t _ p a t h _ l i s t . l h _ f i r s t ; f o r ( ; path ; path = path> p a t h _ l i n k . l e _ n e x t ) // a l l paths { d e l a y = 0 . 0 1 Random : : uniform ( ) ; i f ( path >e x p i r e > (NOW + d e l a y ) ) { Packet p = Packet : : a l l o c ( ) ; s t r u c t hdr_cmn ch = HDR_CMN ( p ) ; s t r u c t h d r _ i p i h = HDR_IP ( p ) ; s t r u c t hdr_aodv_ping ping = HDR_AODV_PING ( p ) ; ping >t y p e = AODVTYPE_PING ; ping > s r c = i nd ex ; ping >d s t = r t > r t _ d s t ; ping >l a s t _ h o p = path>l a s t h o p ; ping > f i r s t _ h o p = path>nexthop ; ping >hop_count = 0 ; ping > p i n g _ r e p l y _ f l a g = 0 ; ping >nr _ nei g h = 0 ; ping >next_hop = path>nexthop ; ch>ptype ( ) ch> s i z e ( ) ch> i f a c e ( ) ch> e r r o r ( ) ch>ad d r _ t y p e ( ) ch>prev_hop_ ch>timestamp ( ) ch>next_hop ( ) ch> d i r e c t i o n ( ) // ih >daddr ( ) ih >daddr ( ) = = = = = = = = = // s r c of ping // dst of ping

/ / jump by jump

PT_AODV ; IP_HDR_LEN + ping > s i z e ( ) ; 2; 0; NS_AF_INET ; i nd ex ; NOW + d e l a y ; / / s e t t h e time path>nexthop ; hdr_cmn : : DOWN; / / down t o phy / / jump by jump

= path >nexthop ; = r t > r t _ d s t ;

72

A.1. C++

ih >saddr ( ) ih >s p o r t ( ) ih >d p o r t ( ) ih > t t l _ path> e x p i r e r t > r t _ e x p i r e

= = = =

i nd ex ; RT_PORT ; RT_PORT ; NETWORK_DIAMETER ; / / s e t new t i m e o u t / / s e t new t i m e o u t

= NOW + ACTIVE_PATH_TIMEOUT ; = NOW + ACTIVE_ROUTE_TIMEOUT ;

# i f d e f SA_DEBUG f p r i n t f ( stdout , " Pi ng from [%d ] at t = %.7 f v i a \%d to [%d ] \ n " , index , ch>timestamp ( ) , path>nexthop , r t > r t _ d s t ) ; #e n d i f / / dont send a l l t h e p a c k e t s a t t h e same time , but / / t h i s has t o be t a k e n / / i n t o a c c o u n t f o r t h e timestamp ! ! Sched ul er : : i n s t a n c e ( ) . s ched ul e ( t a r g e t _ , p , d e l a y ) ; } } } r t n = r t > r t _ l i n k . l e _ n e x t ; } } v o i d AODV : : sendPong ( ns ad d r _ t dest , Packet p ) { // create a ping response Packet pong = Packet : : a l l o c ( ) ; / / new p a c k e t s t r u c t hdr_cmn ch = HDR_CMN ( pong ) ; s t r uct hdr_ip i h = HDR_IP ( pong ) ; s t r u c t hdr_aodv_ping ping = HDR_AODV_PING ( pong ) ; s t r u c t hdr_cmn ch_s = HDR_CMN ( p ) ; / / use t h e o l d v a l u e s t o i n i t i a l i s e s t r uct hdr_ip i h _ s = HDR_IP ( p ) ; s t r u c t hdr_aodv_ping p i ng _ s = HDR_AODV_PING ( p ) ; // f i n d the route en try aodv_rt_entry r t ; r t = r t a b l e . r t _ l o o k u p ( ping_s > s r c ) ; i f ( r t ! = NULL ) { AODV_Path path ; path = r t >path_lookup ( ping_s >l a s t _ h o p ) ; i f ( path ! = NULL ) { path> e x p i r e = NOW + ACTIVE_PATH_TIMEOUT ; / / s e t new t i m e o u t r t > r t _ e x p i r e = NOW + ACTIVE_ROUTE_TIMEOUT ; / / s e t new t i m e o u t } else { # i f d e f SA_DEBUG f p r i n t f ( stdout , " no path to r e t u r n ping " ) ; #e n d i f } } else { # i f d e f SA_DEBUG f p r i n t f ( stdout , " no r o ut e to r e t u r n ping " ) ; #e n d i f } ping >t y p e ping > s r c ping >d s t = AODVTYPE_PING ; = ping_s > s r c ; = ping_s >d s t ;

/ / do not o v e r w r i t e t h e s o u r c e and d e s t

73

A.1. C++

ping > f i r s t _ h o p = ping_s >l a s t _ h o p ; ping >l a s t _ h o p = ping_s > f i r s t _ h o p ; ping >hop_count = ping_s >hop_count ; ping > p i n g _ r e p l y _ f l a g = 1 ; ping >nr _ nei g h = ping_s >nr _ nei g h ; ping >next_hop = d es t ; ch>ptype ( ) ch> s i z e ( ) ch> i f a c e ( ) ch> e r r o r ( ) ch>ad d r _ t y p e ( ) ch>prev_hop_ ch>timestamp ( ) ch>next_hop ( ) ch> d i r e c t i o n ( ) ih >saddr ( ) ih >daddr ( ) ih >s p o r t ( ) ih >d p o r t ( ) ih > t t l _ = PT_AODV ; = IP_HDR_LEN + ping > s i z e ( ) ; = = = = = = = = = = = = 2; 0; NS_AF_INET ; i nd ex ; ch_s >timestamp ( ) ; ch_s >prev_hop_ ; hdr_cmn : : DOWN; i nd ex ; ping_s > s r c ; RT_PORT ; RT_PORT ; i h_ s > t t l _ ;

Packet : : f r e e ( p ) ; // d e l e t e the old packet # i f d e f SA_DEBUG f p r i n t f ( stdout , " Pong from [%d ] at t = %.7 f v i a \%d to [%d ] \ n " , index , ch>timestamp ( ) , ch>next_hop ( ) , ping > s r c ) ; #e n d i f Sched ul er : : i n s t a n c e ( ) . s ched ul e ( t a r g e t _ , pong , 0 ) ; } v o i d AODV : : r e c v P i n g ( Packet p ) { // r e c e i v e the ping packet s t r u c t h d r _ i p i h = HDR_IP ( p ) ; s t r u c t hdr_cmn ch = HDR_CMN ( p ) ; s t r u c t hdr_aodv_ping ping = HDR_AODV_PING ( p ) ; AODV_Neighbor nb ; / / check t t l i f ( ih > t t l _ == 0) { # i f d e f SA_DEBUG f p r i n t f ( stdout , " drop %d : at node %d from %d t t l %d \ n " , ih >f l o w i d ( ) , index , ping >dst , ih > t t l ( ) ) ; #e n d i f drop ( p , DROP_RTR_TTL ) ; return ; } / / / / AT SOURCE / / i f ( ping > s r c == i nd ex ) { / / s h o u l d not o c c u r , as we do not want t o r e c e i v e our own p a c k e t s i f ( ping > p i n g _ r e p l y _ f l a g == 0) { # i f d e f SA_DEBUG f p r i n t f ( stdout , " r e c e i v e d my own ping ! \ n " ) ; #e n d i f drop ( p , DROP_RTR_NO_ROUTE ) ; return ; }

74

A.1. C++

/ / p i n g came back t o o r i g i n else { double r t t ; r t t = NOW ch>timestamp ( ) ; # i f d e f SA_DEBUG f p r i n t f ( stdout , " ping had r t t %f from [%d ] to node [%d ] \ n " , r t t , index , ping >d s t ) ; #e n d i f aodv_rt_entry entry ; e n t r y = r t a b l e . r t _ l o o k u p ( ping >d s t ) ; i f ( e n t r y == NULL ) / / no r t e n t r y { # i f d e f SA_DEBUG f p r i n t f ( stdout , " ping to a d es t . t hat does not e x i s t \ n " ) ; #e n d i f drop ( p , DROP_RTR_NO_ROUTE ) ; return ; } else { AODV_Path path ; path = ent r y >path_lookup ( ping >l a s t _ h o p ) ; / / r e t u r n s t h e path with same f i r s t hop i f ( path == NULL ) { # i f d e f SA_DEBUG f p r i n t f ( stdout , " pinged path a l r e a d y d e l e t e d \ n " ) ; r t a b l e . rt_dumptable ( ) ; #e n d i f drop ( p , DROP_RTR_NO_ROUTE ) ; return ; } else { path> r t t = r t t ; path> e x p i r e = NOW + ACTIVE_PATH_TIMEOUT ; / / update l i f e t i m e i f ( ping >nr _ nei g h ! = 0) path >nr _ nei g h = ping >nr _ nei g h ; ent r y >s ched _ cal c _ w e i g h t s ( ) ; Packet : : f r e e ( p ) ; return ; } } } } / / / / AT DESTINATION / / e l s e i f ( ping >d s t == i nd ex ) { # i f d e f SA_DEBUG cout << " r e c e i v e d Pi ng at node " << i nd ex << " from " << ih >saddr ( ) << " t t l " << ih > t t l ( ) << " \ n " ; # endif sendPong ( ch>prev_hop_ , p ) ; / / v i a t h e hop i t came i n return ; } / / / / FORWARD / / else {

75

A.1. C++

// f i n d the route en try aodv_rt_entry entry ; i f ( ping > p i n g _ r e p l y _ f l a g == 0 ) // { e n t r y = r t a b l e . r t _ l o o k u p ( ping >d s t } else // { e n t r y = r t a b l e . r t _ l o o k u p ( ping > s r c }

t h i s i s a p i n g message ); if ); i t i s a pong

i f ( e n t r y == NULL ) { drop ( p , DROP_RTR_NO_ROUTE ) ; return ; } else { ent r y > r t _ e x p i r e = NOW + ACTIVE_ROUTE_TIMEOUT ; / / update t h e l i f e t i m e / / f i n d t h e path e n t r y AODV_Path path = ent r y > r t _ p a t h _ l i s t . l h _ f i r s t ; f o r ( ; path ; path = path> p a t h _ l i n k . l e _ n e x t ) { i f ( path >l a s t h o p == ping >l a s t _ h o p ) / / s e a r c h path with same l a s t hop b r eak ; } i f ( path == NULL ) { drop ( p , DROP_RTR_NO_ROUTE ) ; return ; } else { path> e x p i r e = NOW + ACTIVE_PATH_TIMEOUT ; / / s e t t h e new d e s t ping >next_hop = path >nexthop ; ch>next_hop ( ) = path >nexthop ; ch>prev_hop_ = i nd ex ; ch> d i r e c t i o n ( ) = hdr_cmn : : DOWN;

/ / update l i f e t i m e

i f ( ping > p i n g _ r e p l y _ f l a g == 0) / / t h i s i s a p i n g message { path >p i ng _ s ent = NOW; / / i n s e r t t h e n e i g h b o u r s o f t h i s node AODV_Neighbor neigh ; neigh = nbhead . l h _ f i r s t ; / / count t h e n e i g h b o u r s i n t count = 0 ; f o r ( ; neigh ; neigh = ( neigh >n b _ l i n k . l e _ n e x t ) ) { count + + ; } ping >nr _ nei g h += count ; } else { / / s t o r e t h e r t t from h e r e t o t h e d e s t i n a t i o n e n t r y = r t a b l e . r t _ l o o k u p ( ping >d s t ) ; i f ( e n t r y ! = NULL ) { path = ent r y >path_lookup ( ping >d s t ) ; i f ( path ! = NULL ) { path> r t t = NOW path>p i ng _ s ent ;

76

A.1. C++

} } } # i f d e f SA_DEBUG cout << " at node " << i nd ex << " forward Pi ng to " #e n d i f Sched ul er : : i n s t a n c e ( ) . s ched ul e ( t a r g e t _ , p , 0 ) ; } } } } #e n d i f / / PING # i f d e f AODV_INFO v o i d AODV : : s end I nf o ( ) { // p r i n t i n fo rm a tions to the t r a c e f i l e using the i n f o packet Packet p = Packet : : a l l o c ( ) ; s t r u c t hdr_cmn ch = HDR_CMN ( p ) ; / / t h e common header s t r uct hdr_ip ih = HDR_IP ( p ) ; / / t h e I P header s t r u c t hd r _ ao d v _ i nf o i n f o = HDR_AODV_INFO( p ) ; i n f o >t y p e = double d e l a y ; i n f o > s r c = i n f o >d s t = i n f o >a c t i o n = i n f o >path_count= i n f o >next_hop = i n f o >l a s t _ h o p = i n f o >hop_count = i n f o > r t t = ch>ptype ( ) ch> i f a c e ( ) ch> e r r o r ( ) ch>ad d r _ t y p e ( ) ch>prev_hop_ ch> d i r e c t i o n ( ) ih >saddr ( ) ih >daddr ( ) ih >s p o r t ( ) ih >d p o r t ( ) ih > t t l _ drop ( p ) ; } v o i d AODV : : dumpPath ( a o d v _ r t _ e n t r y r t , AODV_Path path , i n t act i o n , i n t num_path ) { / / c o l l e c t a l l t h e i n f o r m a t i o n s we want t o p r i n t out no d e_ i nf o . s r c = no d e_ i nf o . d s t = no d e_ i nf o . path_count= no d e_ i nf o . a c t i o n = no d e_ i nf o . next_hop = no d e_ i nf o . l a s t _ h o p = no d e_ i nf o . hop_count = node_info . r t t = no d e_ i nf o . r t t = s end I nf o ( ) ; } #e n d i f / / INFO #e n d i f i nd ex ; r t > r t _ d s t ; num_path ; action ; path>nexthop ; path>l a s t h o p ; path>hopcount ; path > r t t ; path> e x p i r e ; = = = = = = = = = = = AODVTYPE_INFO ; no d e_ i nf o . s r c ; no d e_ i nf o . d s t ; no d e_ i nf o . a c t i o n ; no d e_ i nf o . path_count ; no d e_ i nf o . next_hop ; no d e_ i nf o . l a s t _ h o p ; no d e_ i nf o . hop_count ; no d e_ i nf o . r t t ; PT_AODV ; 2; 0; NS_AF_INET ; i nd ex ; hdr_cmn : : DOWN; i nd ex ; 1; RT_PORT ; RT_PORT ; 0;

<< ping >d s t << " \ n " ;

/ / down t o phy

/ / dont send i t

//

77

A.1. C++

/ / [ s c h e d u l i n g ] end / Neighbor Management F u n c t i o n s / v o i d AODV : : s end H el l o ( ) { Packet p = Packet : : a l l o c ( ) ; s t r u c t hdr_cmn ch = HDR_CMN ( p ) ; s t r u c t h d r _ i p i h = HDR_IP ( p ) ; s t r u c t hd r _ ao d v _ r ep l y rh = HDR_AODV_REPLY( p ) ; # i f d e f DEBUG f p r i n t f ( s t d e r r , " sending H e l l o from %d at %.2 f \ n " , index , NOW) ; #e n d i f / / DEBUG rh>r p _ t y p e = rh>rp_hop_count= rh>r p _ d s t = rh>r p _ d s t _ s eq no= rh> r p _ l i f e t i m e = ch>ptype ( ) ch> s i z e ( ) ch> i f a c e ( ) ch> e r r o r ( ) ch>ad d r _ t y p e ( ) ch>prev_hop_ = = = = = = AODVTYPE_HELLO ; 0; i nd ex ; seqno ; ( 1 + ALLOWED_HELLO_LOSS ) HELLO_INTERVAL ; PT_AODV ; IP_HDR_LEN + rh> s i z e ( ) ; 2; 0; NS_AF_NONE ; i nd ex ; / / AODV hack i nd ex ; IP_BROADCAST ; RT_PORT ; RT_PORT ;

ih >saddr ( ) = ih >daddr ( ) = ih >s p o r t ( ) = ih >d p o r t ( ) = ih > t t l _ = 1; }

Sched ul er : : i n s t a n c e ( ) . s ched ul e ( t a r g e t _ , p , 0 . 0 ) ;

v o i d AODV : : r e c v H e l l o ( Packet p ) { s t r u c t h d r _ i p i h = HDR_IP ( p ) ; / / CHANGED BY ME ( uncommented t h i s l i n e ) s t r u c t hd r _ ao d v _ r ep l y rp = HDR_AODV_REPLY( p ) ; AODV_Neighbor nb ; nb = nb_lookup ( rp >r p _ d s t ) ; i f ( nb == 0) { n b _ i n s e r t ( rp >r p _ d s t ) ; } else { nb>nb _ ex p i r e = NOW + ( 1 . 5 ALLOWED_HELLO_LOSS HELLO_INTERVAL ) ; } / / CHANGE / / Add a r o u t e t o t h i s n e i gh b o r ih >daddr ( ) = i nd ex ; rp > r p _ s r c = ih >saddr ( ) ; # i f d e f AOMDV rp > r p _ f i r s t _ h o p = i nd ex ; #e n d i f / / AOMDV recvReply ( p ) ; / / CHANGE }

78

A.1. C++

v o i d AODV : : n b _ i n s e r t ( ns ad d r _ t i d ) { / / CHANGE AODV_Neighbor nb ; i f ( ( nb=nb_lookup ( i d ) ) == NULL ) { nb = new AODV_Neighbor ( i d ) ; a s s e r t ( nb ) ; / / CHANGE nb>nb _ ex p i r e = NOW + ( HELLO_INTERVAL ALLOWED_HELLO_LOSS ) ; LIST_INSERT_HEAD (&nbhead , nb , n b _ l i n k ) ; } else { / / CHANGE nb>nb _ ex p i r e = NOW + ( HELLO_INTERVAL ALLOWED_HELLO_LOSS ) ; } } AODV_Neighbor AODV : : nb_lookup ( ns ad d r _ t i d ) { AODV_Neighbor nb = nbhead . l h _ f i r s t ; f o r ( ; nb ; nb = nb>n b _ l i n k . l e _ n e x t ) { i f ( nb>nb_addr == i d ) b r eak ; } r e t u r n nb ; } / C a l l e d when we r e c e i v e e x p l i c i t n o t i f i c a t i o n t h a t a Neighbor i s no l o n g e r r e a c h a b l e . / v o i d AODV : : nb _ d el et e ( ns ad d r _ t i d ) { AODV_Neighbor nb = nbhead . l h _ f i r s t ; log_link_del ( id ) ; seqno += 2 ; / / S e t o f n e i g h b o r s changed a s s e r t ( ( seqno % 2 ) == 0 ) ; f o r ( ; nb ; nb = nb>n b _ l i n k . l e _ n e x t ) { i f ( nb>nb_addr == i d ) { LIST_REMOVE ( nb , n b _ l i n k ) ; d e l e t e nb ; b r eak ; } } Packet p ; handle_link_failure ( id ) ; # i f d e f AOMDV_PACKET_SALVAGING w hi l e ( ( p = ifqueue > f i l t e r ( i d ) ) ) { s t r u c t hdr_cmn ch = HDR_CMN ( p ) ; s t r u c t h d r _ i p i h = HDR_IP ( p ) ; i f ( ! DATA_PACKET ( ch>ptype ( ) ) ) drop ( p , DROP_RTR_HELLO ) ; else {

79

A.1. C++

/ / s a l v a g e t h e p a c k e t u s i n g an a l t e r n a t e path i f a v a i l a b l e . a o d v _ r t _ e n t r y r t = r t a b l e . r t _ l o o k u p ( ih >daddr ( ) ) ; i f ( r t && ( r t > r t _ f l a g s == RTF_UP ) && ( ch>aomdv_salvage_count_ < AOMDV_MAX_SALVAGE_COUNT) ) { ch>aomdv_salvage_count_ += 1 ; forward ( r t , p , NO_DELAY ) ; } e l s e drop ( p , DROP_RTR_HELLO ) ; } } # e l s e / / NO PACKET SALVAGING w hi l e ( ( p = ifqueue > f i l t e r ( i d ) ) ) { drop ( p , DROP_RTR_HELLO ) ; } #e n d i f / / NO PACKET SALVAGING } / P u r g e s a l l timedout Neighbor E n t r i e s r u n s e v e r y HELLO_INTERVAL 1 . 5 s e c o n d s . / v o i d AODV : : nb_purge ( ) { AODV_Neighbor nb = nbhead . l h _ f i r s t ; AODV_Neighbor nbn ; f o r ( ; nb ; nb = nbn ) { nbn = nb>n b _ l i n k . l e _ n e x t ; i f ( nb>nb _ ex p i r e <= NOW) { nb _ d el et e ( nb>nb_addr ) ; } } } # i f d e f AOMDV v o i d AODV : : r ecv R eq ues t ( Packet p ) { s t r u c t h d r _ i p i h = HDR_IP ( p ) ; s t r u c t hd r _ ao d v _ r eq ues t rq = HDR_AODV_REQUEST ( p ) ; a o d v _ r t _ e n t r y rt0 , r t ; B r o a d c a s t I D b = NULL ; bool ki l l _r eques t _pr o pa g a t i o n = f a l s e ; AODV_Path r e v e r s e _ p a t h = NULL ; / I f I have r e c e i v e d my own RREQ j u s t drop i t . / i f ( rq > r q _ s r c == i nd ex ) { Packet : : f r e e ( p ) ; return ; } / I f RREQ has a l r e a d y been r e c e i v e d drop i t , e l s e remember " RREQ i d " < s r c I P , b c a s t ID > . / i f ( ( b = i d _ l o o k u p ( rq>r q _ s r c , rq >r q _ b c a s t _ i d ) ) == NULL ) { / / Cache t h e b r o a d c a s t ID b = i d _ i n s e r t ( rq >r q _ s r c , rq >r q _ b c a s t _ i d ) ; } else kill_request_propag ati on = true ;

80

A.1. C++

/ I f I am a n e i gh b o r t o t h e RREQ s o u r c e , make m y s e l f f i r s t hop on path from s o u r c e t o d e s t . / i f ( rq >rq_hop_count == 0) rq > r q _ f i r s t _ h o p = i nd ex ; / Check i f an e n t r y f o r RREQ s o u r c e e x i s t s a l r e a d y i n r o u t e t a b l e / r t 0 = r t a b l e . r t _ l o o k u p ( rq> r q _ s r c ) ; i f ( r t 0 == 0) { / i f e n t r y not i n t h e r o u t e t a b l e c r e a t e an e n t r y f o r t h e r e v e r s e r o u t e . / r t 0 = r t a b l e . r t _ ad d ( rq > r q _ s r c ) ; } / C r e a t e / update r e v e r s e path ( i . e . path back t o RREQ s o u r c e ) I f RREQ c o n t a i n s more r e c e n t s e q number than r o u t e t a b l e e n t r y update r o u t e en try to source . / i f ( rt0 >r t _ s eq no < rq >r q _ s r c_ s eq no ) { rt0 >r t _ s eq no = rq >r q _ s r c_ s eq no ; rt0 >r t _ a d v e r t i s e d _ h o p s = I N F I N I T Y ; / / [ s c h e d u l i n g ] # i f d e f SA_CHANGE / / p r i n t t h e p a t h s b e f o r e t h e y a r e removed # i f d e f AODV_INFO AODV_Path path = rt0 > r t _ p a t h _ l i s t . l h _ f i r s t ; i n t num_path = rt0 >rt_num_paths_ ; i f ( rt0 >path_empty ( ) == f a l s e ) { f o r ( ; path ; path = path >p a t h _ l i n k . l e _ n e x t ) { num_path ; dumpPath ( rt0 , path , 1 , num_path ) ; } } #e n d i f #e n d i f / / [ s c h e d u l i n g ] end rt0 >p a t h _ d e l e t e ( ) ; / / D e l e t e a l l p r e v i o u s p a t h s t o RREQ s o u r c e rt0 > r t _ f l a g s = RTF_UP ; / I n s e r t new path f o r r o u t e e n t r y t o s o u r c e o f RREQ . ( s r c addr , hop count + 1 , l i f e t i m e , l a s t hop ( f i r s t hop f o r RREQ ) ) / r e v e r s e _ p a t h = rt0 >p a t h _ i n s e r t ( ih >saddr ( ) , rq >rq_hop_count + 1 , NOW + REV_ROUTE_LIFE , rq > r q _ f i r s t _ h o p ) ; / / [ s c h e d u l i n g ] # i f d e f SA_CHANGE # i f d e f AODV_INFO dumpPath ( rt0 , r ev er s e_ p at h , 1 , rt0 >rt_num_paths_ ) ; #e n d i f #e n d i f / / [ s c h e d u l i n g ] end / / CHANGE rt0 >r t _ l a s t _ h o p _ c o u n t = rt0 >path_get_max_hopcount ( ) ; / / CHANGE } / I f a new path with s m a l l e r hop count i s r e c e i v e d ( same seqno , b e t t e r hop count ) t r y t o i n s e r t new path i n r o u t e t a b l e . / e l s e i f ( ( rt0 >r t _ s eq no == rq >r q _ s r c_ s eq no ) && ( rt0 >r t _ a d v e r t i s e d _ h o p s > rq >rq_hop_count ) ) { AODV_Path erp =NULL ;

81

A.1. C++

a s s e r t ( rt0 > r t _ f l a g s == RTF_UP ) ; / / Make s u r e path i s up / I f path a l r e a d y e x i s t s a d j u s t t h e l i f e t i m e o f t h e path . / i f ( ( r e v e r s e _ p a t h = rt0 >d i s j o i n t _ p a t h _ l o o k u p ( ih >saddr ( ) , rq > r q _ f i r s t _ h o p ) ) ) { a s s e r t ( r ev er s e_ p at h >hopcount == ( rq >rq_hop_count + 1 ) ) ; r ev er s e_ p at h >e x p i r e = max ( r ev er s e_ p at h >e x p i r e , (NOW + REV_ROUTE_LIFE ) ) ; } / Got a new a l t e r n a t e d i s j o i n t r e v e r s e path so i n s e r t i t . I . e . no path e x i s t s which has RREQ s o u r c e as n e x t hop and no path with RREQ f i r s t hop as l a s t hop e x i s t s f o r t h i s r o u t e e n t r y . S i m p l y s t a t e d : no path with t h e same l a s t hop e x i s t s a l r e a d y . / e l s e i f ( rt0 >n e w _ d i s j o i n t _ p a t h ( ih >saddr ( ) , rq > r q _ f i r s t _ h o p ) ) { / Only i n s e r t new path i f not too many p a t h s e x i s t s f o r t h i s d e s t i n a t i o n and new path does not d i f f e r too much i n l e n g t h compared t o p r e v i o u s p a t h s / i f ( ( rt0 >rt_num_paths_ < aomdv_max_paths_ ) && ( ( ( rq >rq_hop_count + 1 ) rt0 >path_get_min_hopcount ( ) ) <= ao m d v _ p r i m _ a l t _ p a t h _ l e n _ d i f f _ ) ) { / I n s e r t new ( d i s j o i n t ) r e v e r s e path / r e v e r s e _ p a t h = rt0 > p a t h _ i n s e r t ( ih >saddr ( ) , rq>rq_hop_count + 1 , NOW + REV_ROUTE_LIFE , rq> r q _ f i r s t _ h o p ) ; / / [ s c h e d u l i n g ] # i f d e f SA_CHANGE # i f d e f AODV_INFO dumpPath ( rt0 , r ev er s e_ p at h , 1 , rt0 >rt_num_paths_ ) ; #e n d i f #e n d i f / / [ s c h e d u l i n g ] end / / CHANGE rt0 >r t _ l a s t _ h o p _ c o u n t = rt0 >path_get_max_hopcount ( ) ; / / CHANGE } / I f new path d i f f e r s too much i n l e n g t h compared t o p r e v i o u s p a t h s drop p a c k e t . / i f ( ( ( rq >rq_hop_count + 1 ) rt0 >path_get_min_hopcount ( ) ) > ao m d v _ p r i m _ a l t _ p a t h _ l e n _ d i f f _ ) { Packet : : f r e e ( p ) ; return ; } } / ( RREQ was i n t e n d e d f o r me ) AND ( ( Path with RREQ f i r s t hop as l a s t hop does not e x i s t ) OR ( The path e x i s t s and has l e s s hop count than RREQ ) ) drop p a c k e t . Don t know what t h i s c a s e i s f o r . . . / e l s e i f ( ( rq >r q _ d s t == i nd ex ) && ( ( ( erp = rt0 >p at h_ l o o kup _ l as t ho p ( rq > r q _ f i r s t _ h o p ) ) == NULL ) | | ( ( rq >rq_hop_count + 1 ) > erp >hopcount ) ) ) { Packet : : f r e e ( p ) ; return ; } } / O l d e r seqno ( o r same seqno with h i g h e r hopcount ) , i . e . I have a more r e c e n t r o u t e e n t r y so drop p a c k e t . / else

82

A.1. C++

{ Packet : : f r e e ( p ) ; return ; } / I f r o u t e i s up / i f ( rt0 > r t _ f l a g s == RTF_UP ) { // Res et the s o f t s t a t e rt0 >r t _ r e q _ t i m e o u t = 0 . 0 ; rt0 > r t _ r e q _ l a s t _ t t l = 0 ; rt0 > r t _ r e q _ c n t = 0 ; / F i n d out whether any b u f f e r e d p a c k e t can b e n e f i t from t h e revers e route . / Packet b u f f e r e d _ p k t ; w hi l e ( ( b u f f e r e d _ p k t = rqueue . deque ( rt0 > r t _ d s t ) ) ) { i f ( r t 0 && ( rt0 > r t _ f l a g s == RTF_UP ) ) { forward ( rt0 , b uf f er ed _ p kt , NO_DELAY ) ; } } } / Check r o u t e e n t r y f o r RREQ d e s t i n a t i o n / r t = r t a b l e . r t _ l o o k u p ( rq >r q _ d s t ) ; / I am t h e i n t e n d e d r e c e i v e r o f t h e RREQ so send a RREP / i f ( rq >r q _ d s t == i nd ex ) { i f ( seqno < rq>r q _ d s t _ s eq no ) { seqno = rq>r q _ d s t _ s eq no + 1 ; } / Make s u r e s e q number i s even ( why ? ) / i f ( seqno % 2 ) seqno + + ;

s end R ep l y ( rq>r q _ s r c , 0, index , seqno , MY_ROUTE_TIMEOUT , rq >rq_timestamp , ih >saddr ( ) , rq >r q _ b c a s t _ i d , ih >saddr ( ) ) ;

// // // // // // // //

IP Destination Hop Count ( RREQ ) D e s t I P A d d r e s s D e s t Sequence Num Lifetime timestamp nexthop broadcast i d to i d e n t i f y t h i s route d i s c o v e r y

Packet : : f r e e ( p ) ; } / I have a f r e s h r o u t e e n t r y f o r RREQ d e s t i n a t i o n so send RREP / e l s e i f ( r t && ( r t > r t _ f l a g s == RTF_UP ) && ( r t >r t _ s eq no >= rq >r q _ d s t _ s eq no ) ) { a s s e r t ( ( r t >r t _ s eq no % 2 ) == 0 ) ; / / i s t h e seqno even ? / R e v e r s e path e x i s t s / i f ( reverse_path ) { # i f d e f AOMDV_NODE_DISJOINT_PATHS i f ( b>count == 0) { b>count = 1 ; // route advertisement i f ( r t > r t _ a d v e r t i s e d _ h o p s == I N F I N I T Y )

83

A.1. C++

r t >r t _ a d v e r t i s e d _ h o p s = r t >path_get_max_hopcount ( ) ; # i f d e f SA_CHANGE AODV_Path forward_path = r t >p a t h _ f i n d ( ih >saddr ( ) , i nd ex ) ; #e l s e AODV_Path forward_path = r t >p a t h _ f i n d ( ) ; #e n d i f / / [ s c h e d u l i n g ] argument / / CHANGE r t > r t _ e r r o r = t r u e ; / / CHANGE s end R ep l y ( rq >r q _ s r c , r t >r t _ a d v e r t i s e d _ h o p s , rq >r q _ d s t , r t >rt_seqno , forward_path> e x p i r e NOW, rq >rq_timestamp , ih >saddr ( ) , rq >r q _ b c a s t _ i d , forward_path>l a s t h o p ) ; } #e n d i f / / AOMDV_NODE_DISJOINT_PATHS # i f d e f AOMDV_LINK_DISJOINT_PATHS AODV_Path forward_path = NULL ; AODV_Path r = r t > r t _ p a t h _ l i s t . l h _ f i r s t ; / / Get f i r s t path f o r RREQ d e s t i n a t i o n / Make s u r e we don t answer with t h e same f o r w a r d path t w i c e i n r e s p o n s e t o a c e r t a i n RREQ ( r e c e i v e d more than once ) . E . g . " m i d d l e node " i n " d o u b l e diamond " . / f o r ( ; r ; r = r > p a t h _ l i n k . l e _ n e x t ) { i f ( b>f o r w ar d _ p at h_ l ookup ( r >nexthop , r >l a s t h o p )== NULL ) { forward_path = r ; b r eak ; } } / I f an unused f o r w a r d path i s found and we have not answered along t h i s r e v e r s e path ( f o r t h i s RREQ ) send a RREP back . / i f ( forward_path &&(b>r e v e r s e _ p a t h _ l o o k u p ( r ev er s e_ p at h >nexthop , r ev er s e_ p at h >l a s t h o p ) == NULL ) ) { / Mark t h e r e v e r s e and f o r w a r d path as used ( f o r t h i s RREQ ) . / b> r e v e r s e _ p a t h _ i n s e r t ( r ev er s e_ p at h >nexthop , r ev er s e_ p at h >l a s t h o p ) ; b>f o r w a r d _ p a t h _ i n s e r t ( forward_path>nexthop , forward_path>l a s t h o p ) ; // route advertisement i f ( r t >r t _ a d v e r t i s e d _ h o p s == I N F I N I T Y ) r t >r t _ a d v e r t i s e d _ h o p s = r t >path_get_max_hopcount ( ) ; / / CHANGE r t > r t _ e r r o r = t r u e ; / / CHANGE s end R ep l y ( rq >r q _ s r c , r t >r t _ a d v e r t i s e d _ h o p s , rq >r q _ d s t , r t >rt_seqno , forward_path> e x p i r e NOW, rq >rq_timestamp , ih >saddr ( ) , rq >r q _ b c a s t _ i d , forward_path>l a s t h o p ) ; } #e n d i f / / AOMDV_LINK_DISJOINT_PATHS }

84

A.1. C++

Packet : : f r e e ( p ) ; } / RREQ not i n t e n d e d f o r me and I don t have a f r e s h enough e n t r y f o r RREQ d e s t so f o r w a r d t h e RREQ / else { i f ( kill_request_propagation ) { / / do not p r o p a ga t e a d u p l i c a t e RREQ Packet : : f r e e ( p ) ; return ; } else { ih >saddr ( ) = i nd ex ; / / Maximum s e q u e n c e number s e e n en r o u t e if ( rt ) rq >r q _ d s t _ s eq no = max ( r t >rt_seqno , rq >r q _ d s t _ s eq no ) ; // route advertisement i f ( rt0 >r t _ a d v e r t i s e d _ h o p s == I N F I N I T Y ) rt0 >r t _ a d v e r t i s e d _ h o p s = rt0 >path_get_max_hopcount ( ) ; rq >rq_hop_count = rt0 >r t _ a d v e r t i s e d _ h o p s ; # i f d e f AOMDV_NODE_DISJOINT_PATHS # i f d e f SA_CHANGE rq > r q _ f i r s t _ h o p = ( rt0 >p a t h _ f i n d ( ih >saddr ( ) , i nd ex )) > l a s t h o p ; #e l s e rq > r q _ f i r s t _ h o p = ( rt0 >p a t h _ f i n d ()) > l a s t h o p ; #e n d i f / / [ s c h e d u l i n g ] argument #e n d i f / / AOMDV_NODE_DISJOINT_PATHS forward ( ( a o d v _ r t _ e n t r y ) 0 , p , DELAY ) ; } } } v o i d AODV : : s end R ep l y ( ns ad d r _ t i p d s t , u _ i n t 3 2 _ t hop_count , ns ad d r _ t r p d s t , u _ i n t 3 2 _ t rpseq , u _ i n t 3 2 _ t l i f e t i m e , double timestamp , ns ad d r _ t nexthop , u _ i n t 3 2 _ t b c a s t _ i d , ns ad d r _ t r p _ f i r s t _ h o p ) { Packet p = Packet : : a l l o c ( ) ; s t r u c t hdr_cmn ch = HDR_CMN ( p ) ; s t r u c t h d r _ i p i h = HDR_IP ( p ) ; s t r u c t hd r _ ao d v _ r ep l y rp = HDR_AODV_REPLY( p ) ; # i f d e f DEBUG f p r i n t f ( s t d e r r , " sending R ep l y from %d at %.2 f \ n " , index , NOW ) ; #e n d i f / / DEBUG rp >r p _ t y p e = rp >rp_hop_count= rp >r p _ d s t = rp >r p _ d s t _ s eq no= rp > r p _ s r c = rp > r p _ l i f e t i m e = rp >rp_timestamp= rp >r p _ b c a s t _ i d = rp > r p _ f i r s t _ h o p = ch>ptype ( ) ch> s i z e ( ) ch> i f a c e ( ) ch> e r r o r ( ) ch>ad d r _ t y p e ( ) = = = = = AODVTYPE_RREP ; hop_count ; rpdst ; r p s eq ; i nd ex ; lifetime ; timestamp ; bcast_id ; rp_first_hop ; PT_AODV ; IP_HDR_LEN + rp > s i z e ( ) ; 2; 0; AF_INET ;

85

A.1. C++

ch>next_hop_

= nexthop ;

ch> x m i t _ f a i l u r e _ = a o d v _ r t _ f a i l e d _ c a l l b a c k ; ch> x m i t _ f a i l u r e _ d a t a _ = ( v o i d ) t h i s ; ih >saddr ( ) ih >daddr ( ) ih >s p o r t ( ) ih >d p o r t ( ) ih > t t l _ } v o i d AODV : : r e c v R e p l y ( Packet p ) { s t r u c t hdr_cmn ch = HDR_CMN ( p ) ; s t r u c t h d r _ i p i h = HDR_IP ( p ) ; s t r u c t hd r _ ao d v _ r ep l y rp = HDR_AODV_REPLY( p ) ; a o d v _ r t _ e n t r y rt0 , r t ; B r o a d c a s t I D b = NULL ; AODV_Path forward_path = NULL ; / I f I r e c e i v e a RREP with m y s e l f as s o u r c e drop p a c k e t ( s h o u l d not o c c u r ) . Comment : r p _ d s t i s t h e s o u r c e o f t h e RREP , o r r a t h e r t h e d e s t i n a t i o n o f t h e RREQ . / i f ( rp >r p _ d s t == i nd ex ) { Packet : : f r e e ( p ) ; return ; } / Check r o u t i n g t a b l e f o r a path t o ( RREQ ) d e s t i n a t i o n / r t = r t a b l e . r t _ l o o k u p ( rp >r p _ d s t ) ; / I f a path t o ( RREQ ) d e s t i n a t i o n does not e x i s t a l r e a d y we add a f o r w a r d path e n t r y t o t h e ( RREQ ) d e s t i n a t i o n / i f ( r t == 0) { r t = r t a b l e . r t _ ad d ( rp >r p _ d s t ) ; } / I f RREP c o n t a i n s more r e c e n t seqno f o r ( RREQ ) d e s t i n a t i o n d e l e t e a l l o l d p a t h s and add t h e new f o r w a r d path t o ( RREQ ) d e s t i n a t i o n / i f ( r t >r t _ s eq no < rp >r p _ d s t _ s eq no ) { r t >r t _ s eq no = rp >r p _ d s t _ s eq no ; r t >r t _ a d v e r t i s e d _ h o p s = I N F I N I T Y ; / / [ s c h e d u l i n g ] # i f d e f SA_CHANGE / / remove a l l p a t h s # i f d e f AODV_INFO AODV_Path path = r t > r t _ p a t h _ l i s t . l h _ f i r s t ; i n t num_path = r t >rt_num_paths_ ; f o r ( ; path ; path = path >p a t h _ l i n k . l e _ n e x t ) { num_path; dumpPath ( r t , path , 1 , num_path ) ; } #e n d i f #e n d i f / / [ s c h e d u l i n g ] end r t >p a t h _ d e l e t e ( ) ; r t > r t _ f l a g s = RTF_UP ; / I n s e r t f o r w a r d path t o RREQ d e s t i n a t i o n . / forward_path = r t >p a t h _ i n s e r t ( rp >r p _ s r c , rp >rp_hop_count + 1 , NOW + rp > r p _ l i f e t i m e , rp > r p _ f i r s t _ h o p ) ; / / [ s c h e d u l i n g ] = = = = = i nd ex ; ipdst ; RT_PORT ; RT_PORT ; NETWORK_DIAMETER ;

Sched ul er : : i n s t a n c e ( ) . s ched ul e ( t a r g e t _ , p , 0 . ) ;

86

A.1. C++

# i f d e f SA_CHANGE # i f d e f AODV_INFO dumpPath ( r t , forward_path , 1 , r t >rt_num_paths_ ) ; #e n d i f #e n d i f / / [ s c h e d u l i n g ] end / / CHANGE r t >r t _ l a s t _ h o p _ c o u n t = r t >path_get_max_hopcount ( ) ; / / CHANGE } / I f t h e s e q u e n c e number i n t h e RREP i s t h e same as f o r r o u t e e n t r y but with a s m a l l e r hop count t r y t o i n s e r t new f o r w a r d path t o ( RREQ ) d e s t . / e l s e i f ( ( r t >r t _ s eq no == rp >r p _ d s t _ s eq no ) && ( r t >r t _ a d v e r t i s e d _ h o p s > rp>rp_hop_count ) ) { a s s e r t ( r t > r t _ f l a g s == RTF_UP ) ; / I f t h e path a l r e a d y e x i s t s i n c r e a s e path l i f e t i m e / i f ( ( forward_path = r t > d i s j o i n t _ p a t h _ l o o k u p ( rp >r p _ s r c , rp > r p _ f i r s t _ h o p ) ) ) { a s s e r t ( forward_path>hopcount == ( rp>rp_hop_count + 1 ) ) ; forward_path> e x p i r e = max ( forward_path>e x p i r e , NOW + rp> r p _ l i f e t i m e ) ; } / I f t h e path does not a l r e a d y e x i s t , t h e r e i s room f o r i t and i t does not d i f f e r too much i n l e n g t h we add t h e path / e l s e i f ( r t >n e w _ d i s j o i n t _ p a t h ( rp>r p _ s r c , rp > r p _ f i r s t _ h o p ) && ( r t >rt_num_paths_ < aomdv_max_paths_ ) && ( ( rp >rp_hop_count + 1 ) r t >path_get_min_hopcount ( ) <= ao m d v _ p r i m _ al t _ p a t h_ l e n _ d i f f _ ) ) { / I n s e r t f o r w a r d path t o RREQ d e s t i n a t i o n . / forward_path = r t > p a t h _ i n s e r t ( rp >r p _ s r c , rp >rp_hop_count + 1 , NOW + rp > r p _ l i f e t i m e , rp > r p _ f i r s t _ h o p ) ; / / CHANGE / / [ s c h e d u l i n g ] # i f d e f SA_CHANGE # i f d e f AODV_INFO dumpPath ( r t , forward_path , 1 , r t >rt_num_paths_ ) ; #e n d i f #e n d i f / / [ s c h e d u l i n g ] end r t >r t _ l a s t _ h o p _ c o u n t = r t >path_get_max_hopcount ( ) ; / / CHANGE } / Path d i d not e x i s t nor c o u l d i t be added j u s t drop p a c k e t . / else { Packet : : f r e e ( p ) ; return ; } } / The r e c e i v e d RREP d i d not c o n t a i n more r e c e n t i n f o r m a t i o n than r o u t e t a b l e so drop p a c k e t / else { Packet : : f r e e ( p ) ; return ; } / I f r o u t e i s up / i f ( r t > r t _ f l a g s == RTF_UP ) { // Res et the s o f t s t a t e r t >r t _ r e q _ t i m e o u t = 0 . 0 ;

87

A.1. C++

r t > r t _ r e q _ l a s t _ t t l = 0 ; r t >r t _ r e q _ c n t = 0 ; i f ( ih >daddr ( ) == i nd ex ) { / / I am t h e RREP d e s t i n a t i o n # i f d e f DYNAMIC_RREQ_RETRY_TIMEOUT / / T h i s macro does not seem t o be s e t . i f ( rp >r p _ t y p e == AODVTYPE_RREP ) { r t > r t _ d i s c _ l a t e n c y [ r t >h i s t _ i n d x ] = (NOW rp >rp_timestamp ) / ( double ) ( rp >rp_hop_count + 1 ) ; / / i n c r e m e n t i n d x f o r n e x t time r t >h i s t _ i n d x = ( r t > h i s t _ i n d x + 1 ) % MAX_HISTORY ; } #e n d i f / / DYNAMIC_RREQ_RETRY_TIMEOUT } / F i n d out whether any b u f f e r e d p a c k e t can b e n e f i t from t h e forward route . / Packet b u f f e r e d _ p k t ; w hi l e ( ( b u f f e r e d _ p k t = rqueue . deque ( r t > r t _ d s t ) ) ) { i f ( r t && ( r t > r t _ f l a g s == RTF_UP ) ) { forward ( r t , b uf f er ed _ p kt , NO_DELAY ) ; } } } / I f I am t h e i n t e n d e d r e c e i p i e n t o f t h e RREP n o t h i n g more needs t o be done so drop p a c k e t . / i f ( ih >daddr ( ) == i nd ex ) { Packet : : f r e e ( p ) ; return ; } / I f I am not t h e i n t e n d e d r e c e i p i e n t o f t h e RREP c h e c k r o u t e t a b l e f o r a path t o t h e RREP d e s t ( i . e . t h e RREQ s o u r c e ) . / r t 0 = r t a b l e . r t _ l o o k u p ( ih >daddr ( ) ) ; b = i d _ l o o k u p ( ih >daddr ( ) , rp > r p _ b c a s t _ i d ) ; / / Check f o r <RREQ s r c I P , b c a s t ID > t u p l e # i f d e f AOMDV_NODE_DISJOINT_PATHS i f ( ( r t 0 == NULL ) | | ( rt0 > r t _ f l a g s ! = RTF_UP ) | | ( b == NULL ) | | ( b>count ) ) { Packet : : f r e e ( p ) ; return ; } b>count = 1 ; # i f d e f SA_CHANGE AODV_Path r e v e r s e _ p a t h = rt0 >p a t h _ f i n d ( ih >saddr ( ) , i nd ex ) ; / / [ s c h e d u l i n g ] argument #else AODV_Path r e v e r s e _ p a t h = rt0 >p a t h _ f i n d ( ) ; #e n d i f ch>ad d r _ t y p e ( ) = AF_INET ; ch>next_hop_ = r ev er s e_ p at h >nexthop ; ch> x m i t _ f a i l u r e _ = a o d v _ r t _ f a i l e d _ c a l l b a c k ; ch> x m i t _ f a i l u r e _ d a t a _ = ( v o i d ) t h i s ; // route advertisement rp > r p _ s r c = i nd ex ; i f ( r t >r t _ a d v e r t i s e d _ h o p s == I N F I N I T Y )

88

A.1. C++

r t > r t _ a d v e r t i s e d _ h o p s = r t >path_get_max_hopcount ( ) ; rp >rp_hop_count = r t >r t _ a d v e r t i s e d _ h o p s ; # i f d e f SA_CHANGE rp > r p _ f i r s t _ h o p = ( r t >p a t h _ f i n d ( ih >saddr ( ) , i nd ex )) > l a s t h o p ; / / [ s c h e d u l i n g ] argument #e l s e rp > r p _ f i r s t _ h o p = ( r t >p a t h _ f i n d ()) > l a s t h o p ; #e n d i f r ev er s e_ p at h > e x p i r e = NOW + ACTIVE_ROUTE_TIMEOUT ; / / CHANGE r t > r t _ e r r o r = t r u e ; / / CHANGE forward ( rt0 , p , NO_DELAY ) ; #e n d i f / / AOMDV_NODE_DISJOINT_PATHS # i f d e f AOMDV_LINK_DISJOINT_PATHS / Drop t h e RREP p a c k e t i f we do not have a path back t o t h e s o u r c e , o r t h e r o u t e i s marked as down , o r i f we n e v e r r e c e i v e d t h e o r i g i n a l RREQ . / i f ( ( r t 0 == NULL ) | | ( rt0 > r t _ f l a g s ! = RTF_UP ) | | ( b == NULL ) ) { Packet : : f r e e ( p ) ; return ; } / Make s u r e we don t answer along t h e same path t w i c e i n r e s p o n s e t o a c e r t a i n RREQ . T r y t o f i n d an unused ( r e v e r s e ) path t o f o r w a r d t h e RREP . / AODV_Path r e v e r s e _ p a t h = NULL ; AODV_Path r = rt0 > r t _ p a t h _ l i s t . l h _ f i r s t ; f o r ( ; r ; r = r > p a t h _ l i n k . l e _ n e x t ) { i f ( b>r e v e r s e _ p a t h _ l o o k u p ( r >nexthop , r >l a s t h o p ) == NULL ) { reverse_path = r ; b r eak ; } } / I f an unused r e v e r s e path i s found and t h e f o r w a r d path ( f o r t h i s RREP ) has not a l r e a d y been r e p l i e d f o r w a r d t h e RREP . / i f ( r e v e r s e _ p a t h && ( b>f o r w ar d _ p at h_l oo kup ( forward_path>nexthop , forward_path>l a s t h o p ) == NULL ) ) { a s s e r t ( forward_path>nexthop == rp > r p _ s r c ) ; a s s e r t ( forward_path>l a s t h o p == rp > r p _ f i r s t _ h o p ) ; / Mark t h e f o r w a r d and r e v e r s e path used t o answer t h i s RREQ as used . / b> r e v e r s e _ p a t h _ i n s e r t ( r ev er s e_ p at h >nexthop , r ev er s e_ p at h >l a s t h o p ) ; b>f o r w a r d _ p a t h _ i n s e r t ( forward_path>nexthop , forward_path>l a s t h o p ) ; ch>ad d r _ t y p e ( ) = AF_INET ; ch>next_hop_ = r ev er s e_ p at h >nexthop ; ch> x m i t _ f a i l u r e _ = a o d v _ r t _ f a i l e d _ c a l l b a c k ; ch> x m i t _ f a i l u r e _ d a t a _ = ( v o i d ) t h i s ; // route advertisement i f ( r t >r t _ a d v e r t i s e d _ h o p s == I N F I N I T Y ) r t >r t _ a d v e r t i s e d _ h o p s = r t >path_get_max_hopcount ( ) ; rp >rp_hop_count = r t > r t _ a d v e r t i s e d _ h o p s ; rp > r p _ s r c = i nd ex ; r ev er s e_ p at h >e x p i r e = NOW + ACTIVE_ROUTE_TIMEOUT ; / / CHANGE r t > r t _ e r r o r = t r u e ; / / CHANGE f o r w ar d R ep l y ( rt0 , p , NO_DELAY ) ; / / CHANGE ( p r e v i o u s l y used f o r w a r d ( ) ) } else

89

A.1. C++

{ Packet : : f r e e ( p ) ; return ; } #e n d i f / / AOMDV_LINK_DISJOINT_PATH / / [ s c h e d u l i n g ] # i f d e f SA_CHANGE # i f d e f AODV_PING sendPing ( ) ; #e n d i f #e n d i f / / [ s c h e d u l i n g ] end } v o i d AODV : : h a n d l e _ l i n k _ f a i l u r e ( ns ad d r _ t id , b o o l e r r o r ) { aodv_rt_entry rt , rtn ; Packet r e r r = Packet : : a l l o c ( ) ; s t r u c t h d r _ a o d v _ e r r o r r e = HDR_AODV_ERROR ( r e r r ) ; # i f d e f DEBUG f p r i n t f ( s t d e r r , "%s : m ul t i p at h v e r s i o n \ n " , __FUNCTION__ ) ; #e n d i f / / DEBUG re >DestCount = 0 ; f o r ( r t = r t a b l e . head ( ) ; r t ; r t = r t n ) { / / f o r each r t e n t r y AODV_Path path ; r t n = r t > r t _ l i n k . l e _ n e x t ; i f ( ( r t > r t _ f l a g s == RTF_UP ) && ( path= r t >path_lookup ( i d ) ) ) { a s s e r t ( ( r t >r t _ s eq no % 2 ) == 0 ) ; / / [ s c h e d u l i n g ] # i f d e f SA_CHANGE # i f d e f AODV_INFO i n t num_path = r t >rt_num_paths_ 1; dumpPath ( r t , path , 1 , num_path ) ; #e n d i f #e n d i f / / [ s c h e d u l i n g ] end r t >p a t h _ d e l e t e ( i d ) ; i f ( r t >path_empty ( ) ) { r t >r t _ s eq no + + ; r t >r t _ s eq no = max ( r t >rt_seqno , r t >r t _ hi g hes t _ s eq n o _ h e a r d ) ; / / CHANGE i f ( r t > r t _ e r r o r ) { re >unr eachab l e_ d s t [ re >DestCount ] = r t > r t _ d s t ; re >unr eachab l e_ d s t _ s eq no [ re >DestCount ] = r t >r t _ s eq no ; # i f d e f DEBUG f p r i n t f ( s t d e r r , "%s (% f ) : %d \ t (%d \ t%u\ t%d ) \ n " , __FUNCTION__ , NOW, index , re >unr eachab l e_ d s t [ re >DestCount ] , re >unr eachab l e_ d s t _ s eq no [ re >DestCount ] , i d ) ; #e n d i f / / DEBUG re >DestCount += 1 ; r t > r t _ e r r o r = f a l s e ; } / / CHANGE rt_down ( r t ) ; } } }

90

A.1. C++

i f ( ( re >DestCount > 0) && ( e r r o r ) ) { # i f d e f DEBUG f p r i n t f ( stdout , "%s (% f ) : %d \ t s end i ng RERR . . . \ n " , __FUNCTION__ , NOW, i nd ex ) ; #e n d i f / / DEBUG sendError ( rerr , f al s e ) ; } else { Packet : : f r e e ( r e r r ) ; } } v o i d AODV : : rt_down ( a o d v _ r t _ e n t r y r t ) { / Make s u r e t h a t you don t " down " a r o u t e more than once . / # i f d e f DEBUG f p r i n t f ( s t d e r r , "%s : m ul t i p at h v e r s i o n \ n " , __FUNCTION__ ) ; #e n d i f / / DEBUG i f ( r t > r t _ f l a g s == RTF_DOWN) { return ; } a s s e r t ( r t >r t _ s eq no % 2 ) ; / / i s t h e seqno odd ? r t > r t _ f l a g s = RTF_DOWN ; r t >r t _ a d v e r t i s e d _ h o p s = I N F I N I T Y ; / / [ s c h e d u l i n g ] # i f d e f SA_CHANGE / / p r i n t t h e p a t h s b e f o r e t h e y a r e removed # i f d e f AODV_INFO AODV_Path path = r t > r t _ p a t h _ l i s t . l h _ f i r s t ; i n t num_path = r t >rt_num_paths_ ; f o r ( ; path ; path = path>p a t h _ l i n k . l e _ n e x t ) { num_path; dumpPath ( r t , path , 1 , num_path ) ; } #e n d i f #e n d i f / / [ s c h e d u l i n g ] end r t >p a t h _ d e l e t e ( ) ; r t > r t _ e x p i r e = 0 ; } / rt_down f u n c t i o n / v o i d AODV : : r e c v E r r o r ( Packet p ) { s t r u c t h d r _ i p i h = HDR_IP ( p ) ; s t r u c t h d r _ a o d v _ e r r o r r e = HDR_AODV_ERROR ( p ) ; aodv_rt_entry r t ; u_int8_t i ; Packet r e r r = Packet : : a l l o c ( ) ; s t r u c t h d r _ a o d v _ e r r o r nre = HDR_AODV_ERROR ( r e r r ) ; # i f d e f DEBUG f p r i n t f ( s t d e r r , "%s : m ul t i p at h v e r s i o n \ n " , __FUNCTION__ ) ; #e n d i f / / DEBUG

nre >DestCount = 0 ; / / F o r each u n r e a c h a b l e d e s t i n a t i o n f o r ( i =0; i < re >DestCount ; i ++)

91

A.1. C++

{ AODV_Path path ; / Get r o u t e e n t r y f o r u n r e a c h a b l e d e s t / r t = r t a b l e . r t _ l o o k u p ( re >unr eachab l e_ d s t [ i ] ) ; / I f r o u t e e n t r y e x i s t s , r o u t e i s up , a path t o t h e u n r e a c h a b l e d e s t i n a t i o n e x i s t s through t h e n e i g b o r from which RERR was r e c e i v e d , and my s e q u e n c e number i s not more r e c e n t d e l e t e path and add i t t o t h e RERR message I w i l l send . / i f ( r t && ( r t > r t _ f l a g s == RTF_UP ) && ( path = r t >path_lookup ( ih >saddr ( ) ) ) && ( r t >r t _ s eq no <= re >unr eachab l e_ d s t _ s eq no [ i ] ) ) { a s s e r t ( ( r t >r t _ s eq no % 2 ) == 0 ) ; / / i s t h e seqno even ? / / [ s c h e d u l i n g ] # i f d e f SA_CHANGE # i f d e f AODV_INFO i n t num_path = r t >rt_num_paths_ 1; dumpPath ( r t , path , 1 , num_path ) ; #e n d i f #e n d i f / / [ s c h e d u l i n g ] end r t >p a t h _ d e l e t e ( ih >saddr ( ) ) ; r t >r t _ hi g hes t _ s eq n o _ he a r d = max ( r t >r t _ hi g hes t _ s eq no _ hear d , re >unr eachab l e_ d s t _ s eq no [ i ] ) ; i f ( r t >path_empty ( ) ) { r t >r t _ s eq no = r t >r t _ hi g hes t _ s eq n o _ h e ar d ; rt_down ( r t ) ; / / CHANGE i f ( r t > r t _ e r r o r ) { nre >unr eachab l e_ d s t [ nre >DestCount ] = r t > r t _ d s t ; nre >unr eachab l e_ d s t _ s eq no [ nre >DestCount ] = r t >r t _ s eq no ; nre >DestCount += 1 ; r t > r t _ e r r o r = f a l s e ; } / / CHANGE } } } / B r o a d c a s t RERR i f any b r o k e n p a t h s were found . / i f ( nre >DestCount > 0) { # i f d e f DEBUG f p r i n t f ( s t d e r r , "%s (% f ) : %d \ t sending RERR . . . \ n " , __FUNCTION__ , NOW, i nd ex ) ; #e n d i f / / DEBUG sendError ( r e r r ) ; } else { Packet : : f r e e ( r e r r ) ; } Packet : : f r e e ( p ) ; } #e n d i f / /AOMDV

Listing A.2: aodv.cc

92

A.1. C++

A.1.3. aodv_rtable.h
/ Mode : C + + ; cb a s i c o f f s e t : 4 ; tabwidth : 4 ; i n d e n ttabsmode : t / / C o p y r i g h t ( c ) 1 9 9 7 , 1998 C a r n e g i e Mellon U n i v e r s i t y . A l l R i g h t s Reserved . P e r m i s s i o n t o use , copy , modify , and d i s t r i b u t e t h i s s o f t w a r e and i t s documentation i s h e r e b y gr a n t e d ( i n c l u d i n g f o r commercial o r f o r p r o f i t use ) , p r o v i d e d t h a t both t h e c o p y r i g h t n o t i c e and t h i s p e r m i s s i o n n o t i c e appear i n a l l c o p i e s o f t h e s o f t w a r e , d e r i v a t i v e works , o r m o d i f i e d v e r s i o n s , and any p o r t i o n s t h e r e o f , and t h a t both n o t i c e s appear i n s u p p o r t i n g documentation , and t h a t c r e d i t i s g i v e n t o C a r n e g i e Mellon U n i v e r s i t y i n a l l p u b l i c a t i o n s r e p o r t i n g on d i r e c t o r i n d i r e c t use o f t h i s code o r i t s d e r i v a t i v e s . ALL CODE , SOFTWARE , PROTOCOLS , AND ARCHITECTURES DEVELOPED BY THE CMU MONARCH PROJECT ARE EXPERIMENTAL AND ARE KNOWN TO HAVE BUGS , SOME OF WHICH MAY HAVE SERIOUS CONSEQUENCES . CARNEGIE MELLON PROVIDES T H I S SOFTWARE OR OTHER INTELLECTUAL PROPERTY IN I T S AS I S CONDITION , AND ANY EXPRESS OR IMPLIED WARRANTIES , INCLUDING , BUT NOT LIMITED TO , THE IMPLIED WARRANTIES OF MERCHANTABILITY AND F I T N E S S FOR A PARTICULAR PURPOSE ARE DISCLAIMED . IN NO EVENT SHALL CARNEGIE MELLON UNIVERSITY BE L I A B L E FOR ANY DIRECT , INDIRECT , INCIDENTAL , S P E C I A L , EXEMPLARY , OR CONSEQUENTIAL DAMAGES ( INCLUDING , BUT NOT LIMITED TO , PROCUREMENT OF SUBSTITUTE GOODS OR S E R V I C E S ; LOSS OF USE , DATA , OR P R O F I T S ; OR BUSINESS INTERRUPTION ) HOWEVER CAUSED AND ON ANY THEORY OF L I A B I L I T Y , WHETHER IN CONTRACT , S T R I C T L I A B I L I T Y , OR TORT ( INCLUDING NEGLIGENCE OR OTHERWISE ) ARISING IN ANY WAY OUT OF THE USE OF T H I S SOFTWARE OR INTELLECTUAL PROPERTY , EVEN I F ADVISED OF THE P O S S I B I L I T Y OF SUCH DAMAGE . C a r n e g i e Mellon e n c o u r a ge s ( but does not r e q u i r e ) u s e r s o f t h i s s o f t w a r e o r i n t e l l e c t u a l p r o p e r t y t o r e t u r n any improvements o r e x t e n s i o n s t h a t t h e y make , and t o gr a n t C a r n e g i e Mellon t h e r i g h t s t o r e d i s t r i b u t e t h e s e changes w i t h o u t encumbrance . The AODV code d e v e l o p e d by t h e CMU/MONARCH group was o p t i m i z e d and tuned by Samir Das and Mahesh Marina , U n i v e r s i t y o f C i n c i n n a t i . The work was p a r t i a l l y done i n Sun M i c r o s y s t e m s . # # P r o j e c t : S e m e s t e r T h e s i s S S 06: # E v a l u a t i o n o f s c h e d u l i n g methods o v e r # m u l t i p a t h r o u t i n g i n w i r e l e s s m o b i l e Ad Hoc n e t w o r k s # # A u t h o r s : R e gu l a Goenner , Dominik Schatzmann # # # Date : J u l y 2006 # # The code has been m o d i e f i e d by R . Goenner and D . Schatzmann , # m o d i f i c a t i o n s a r e i n d i c a t e d with t h e tag / / [ s c h e d u l i n g ] # and t h e y can be a c t i v a t e d by u s i n g # d e f i n e SA_CHANGE # / # i f n d e f _ _ ao d v _ r t ab l e_ h_ _ #d e f i n e _ _ ao d v _ r t ab l e_ h_ _ #i n c l u d e #i n c l u d e #i n c l u d e #i n c l u d e #i n c l u d e < a s s e r t . h> < s y s / t y p es . h> < c o n f i g . h> < l i b / bsd l i s t . h> < s c h e d u l e r . h>

#d e f i n e CURRENT_TIME Sched ul er : : i n s t a n c e ( ) . c l o c k ( ) #d e f i n e I N F I N I T Y 2 0 x f f / / [ s c h e d u l i n g ] / / we need a t i m e o u t f o r each path , s e t i t t h e same as t h e r o u t e t i m e o u t #d e f i n e ACTIVE_PATH_TIMEOUT 10 / / 10 s e c o n d s / / [ s c h e d u l i n g ] end

93

A.1. C++

/ AODV Neighbor Cache E n t r y / c l a s s AODV_Neighbor { f r i e n d c l a s s AODV ; f r i end cl as s aodv_rt_entry ; public : AODV_Neighbor ( u _ i n t 3 2 _ t a ) { nb_addr = a ; } protected : LIST_ENTRY ( AODV_Neighbor ) n b _ l i n k ; ns ad d r _ t nb_addr ; double nb _ ex p i r e ; / / ALLOWED_HELLO_LOSS HELLO_INTERVAL }; LIST_HEAD ( aodv_ncache , AODV_Neighbor ) ; # i f d e f AOMDV / AODV Path l i s t data s t r u c t u r e / c l a s s AODV_Path { f r i e n d c l a s s AODV ; f r i end cl as s aodv_rt_entry ; public : AODV_Path ( ns ad d r _ t nh , u _ i n t 1 6 _ t h , double ex p i r e_ t i m e , ns ad d r _ t l h =0) { nexthop = nh ; hopcount = h; expire = expire_time ; ts = Sched ul er : : i n s t a n c e ( ) . c l o c k ( ) ; lasthop = lh ; / / [ s c h e d u l i n g ] # i f d e f SA_CHANGE rtt = 1000.0; nr _ nei g h = INT_MAX ; #e n d i f / / [ s c h e d u l i n g ] end / / CHANGE error = false ; / / CHANGE } void printPath ( ) { p r i n t f ( " %6d %6d %6d \ n " , nexthop , hopcount , l a s t h o p ) ; } void printPaths ( ) { AODV_Path p = t h i s ; f o r ( ; p ; p = p> p a t h _ l i n k . l e _ n e x t ) { p>p r i n t P a t h ( ) ; } } protected : LIST_ENTRY ( AODV_Path ) p a t h _ l i n k ; ns ad d r _ t nexthop ; / / nexthop a d d r e s s u_int16_t hopcount ; / / hopcount through t h i s nexthop double expire ; / / e x p i r a t i o n timeout double ts ; / / time when we saw t h i s nexthop ns ad d r _ t lasthop ; // lasthop address / / CHANGE bool error ;

94

A.1. C++

/ / CHANGE / / [ s c h e d u l i n g ] # i f d e f SA_CHANGE double rtt ; int nr _ nei g h ; double p i ng _ s ent ; #e n d i f / / [ s c h e d u l i n g ] end }; LIST_HEAD ( aodv_paths , AODV_Path ) ; #e n d i f / / AOMDV / AODV P r e c u r s o r l i s t data s t r u c t u r e / c l a s s AODV_Precursor { f r i e n d c l a s s AODV ; f r i end cl as s aodv_rt_entry ; public : AODV_Precursor ( u _ i n t 3 2 _ t a ) { pc_addr = a ; } protected : LIST_ENTRY ( AODV_Precursor ) p c _ l i n k ; ns ad d r _ t pc_addr ; // p rec u rs o r address }; LIST_HEAD ( ao d v _ p r ecur s o r s , AODV_Precursor ) ;

/ Route T a b l e E n t r y / cl as s aodv_rt_entry { f r i end cl as s aodv_rtable ; f r i e n d c l a s s AODV ; f r i end cl as s LocalRepairTimer ; public : aodv_rt_entry ( ) ; ~aodv_rt_entry ( ) ; v o i d n b _ i n s e r t ( ns ad d r _ t i d ) ; AODV_Neighbor nb_lookup ( ns ad d r _ t i d ) ; # i f d e f AOMDV AODV_Path p a t h _ i n s e r t ( ns ad d r _ t nexthop , u _ i n t 1 6 _ t hopcount , double ex p i r e_ t i m e , ns ad d r _ t l a s t h o p = 0 ) ; AODV_Path AODV_Path bool path_lookup ( ns ad d r _ t i d ) ; / / l o o k u p path by nexthop

d i s j o i n t _ p a t h _ l o o k u p ( ns ad d r _ t nexthop , ns ad d r _ t l a s t h o p ) ; n e w _ d i s j o i n t _ p a t h ( ns ad d r _ t nexthop , ns ad d r _ t l a s t h o p ) ; l o o k u p path by l a s t h o p d e l e t e path by nexthop d e l e t e a l l paths d e l e t e l o n g e s t path path l i s t empty ? ) ; / / f i n d a path t o d e s t f i n d a path t o d e s t

AODV_Path p at h_ l o o kup _ l as t ho p ( ns ad d r _ t i d ) ; // void p a t h _ d e l e t e ( ns ad d r _ t i d ) ; // void path_delete ( void ) ; // void path_delete_longest ( void ) ; // bool path_empty ( v o i d ) ; // # i f d e f SA_CHANGE AODV_Path p a t h _ f i n d ( ns ad d r _ t s r c , ns ad d r _ t i nd ex #else AODV_Path p a t h _ f i n d ( ) ; // #e n d i f

95

A.1. C++

AODV_Path path_findMinHop ( v o i d ) ; / / f i n d t h e s h o r t e s t path u_int16_t path_get_max_hopcount ( v o i d ) ; u_int16_t path_get_min_hopcount ( v o i d ) ; double p at h_ g et _ m ax _ ex p i r at i o n_ t i m e ( v o i d ) ; void path_purge ( v o i d ) ; #e n d i f / / AOMDV void p c _ i n s e r t ( ns ad d r _ t i d ) ; AODV_Precursor pc_lookup ( ns ad d r _ t i d ) ; void p c _ d e l e t e ( ns ad d r _ t i d ) ; void pc_delete ( void ) ; bool pc_empty ( v o i d ) ; double u_int8_t int rt_req_timeout ; rt_req_cnt ; aomdv_max_paths_ ; / / when I can send a n o t h e r r e q / / number o f r o u t e r e q

protected : LIST_ENTRY ( a o d v _ r t _ e n t r y ) r t _ l i n k ; ns ad d r _ t rt_dst ; u_int32_t r t _ s eq no ; / u _ i n t 8 _ t r t _ i n t e r f a c e ; / / / [ s c h e d u l i n g ] # i f d e f SA_CHANGE # i f d e f AOMDV int s ched _ t y p e ; void s ched _ cal c _ w e i g h t s ( ) ; AODV_Path sched_get_path ( ) ; void path_ping ( ) ; int weights ; void path_dumptable ( ) ; ns ad d r _ t tx_rx_id ; #e n d i f #e n d i f / / [ s c h e d u l i n g ] end # i f n d e f AOMDV u_int16_t r t _ ho p s ; #e l s e u_int16_t rt_advertised_hops ; #e n d i f / / AOMDV int rt_last_hop_count ;

/ / c a l c u l a t e t h e w e i gt h i n g / / s e l e c t a path

// s t o r e the d es t

/ / hop count / / a d v e r t i s e d hop count

/ / l a s t v a l i d hop count

# i f n d e f AOMDV ns ad d r _ t r t _ nex t ho p ; #e l s e aodv_paths r t _ p a t h _ l i s t ; u_int32_t r t _ hi g hes t _ s eq n o _ h e a r d ; int rt_num_paths_ ; #e n d i f / / AOMDV / / CHANGE bool / / CHANGE

/ / n e x t hop I P a d d r e s s // l i s t of paths

rt_error ;

/ l i s t o f p r e c u r s o r s / aodv_precursors r t _ p c l i s t ; double rt_expire ; u_int8_t rt_flags ; #d e f i n e RTF_DOWN 0 #d e f i n e RTF_UP 1 #d e f i n e RTF_IN_REPAIR 2

/ / when e n t r y e x p i r e s

96

A.1. C++

#d e f i n e MAX_HISTORY 3 double r t _ d i s c _ l a t e n c y [ MAX_HISTORY ] ; char hist_indx ; int rt_req_last_ttl ;

/ / l a s t t t l v a l u e used

/ a l i s t of neighbors that are using t h i s route . / aodv_ncache rt_nblist ; };

/ The R o u t i n g T a b l e / cl as s aodv_rtable { # i f d e f SA_CHANGE f r i e n d c l a s s AODV ; // [ scheduling ] #e n d i f public : a o d v _ r t a b l e ( ) { L I S T _ I N I T (& r t head ) ; } aodv_rt_entry head ( ) { r e t u r n r t head . l h _ f i r s t ; }

a o d v _ r t _ e n t r y r t _ ad d ( ns ad d r _ t i d ) ; void r t _ d e l e t e ( ns ad d r _ t i d ) ; a o d v _ r t _ e n t r y r t _ l o o k u p ( ns ad d r _ t i d ) ; void rt_dumptable ( ) ; bool rt_has_active_route ( ) ; / / [ s c h e d u l i n g ] # i f d e f SA_CHANGE int s ched _ t y p e ; #e n d i f / / [ s c h e d u l i n g ] end int aomdv_max_paths_ ; private : LIST_HEAD ( aodv_rthead , a o d v _ r t _ e n t r y ) r t head ; }; #e n d i f / _ a o d v _ _ r t a b l e _ h _ _ /

Listing A.3: aodv_rtable.h

97

A.1. C++

A.1.4. aodv_rtable.cc
/ Mode : C + + ; cb a s i c o f f s e t : 4 ; tabwidth : 4 ; i n d e n ttabsmode : t / / C o p y r i g h t ( c ) 1 9 9 7 , 1998 C a r n e g i e Mellon U n i v e r s i t y . A l l Rights Reserved . P e r m i s s i o n t o use , copy , modify , and d i s t r i b u t e t h i s s o f t w a r e and i t s documentation i s h e r e b y gr a n t e d ( i n c l u d i n g f o r commercial o r f o r p r o f i t use ) , p r o v i d e d t h a t both t h e c o p y r i g h t n o t i c e and t h i s p e r m i s s i o n n o t i c e appear i n a l l c o p i e s o f t h e s o f t w a r e , d e r i v a t i v e works , o r m o d i f i e d v e r s i o n s , and any p o r t i o n s t h e r e o f , and t h a t both n o t i c e s appear i n s u p p o r t i n g documentation , and t h a t c r e d i t i s g i v e n t o C a r n e g i e Mellon U n i v e r s i t y i n a l l p u b l i c a t i o n s r e p o r t i n g on d i r e c t o r i n d i r e c t use o f t h i s code o r i t s d e r i v a t i v e s . ALL CODE , SOFTWARE , PROTOCOLS , AND ARCHITECTURES DEVELOPED BY THE CMU MONARCH PROJECT ARE EXPERIMENTAL AND ARE KNOWN TO HAVE BUGS , SOME OF WHICH MAY HAVE SERIOUS CONSEQUENCES . CARNEGIE MELLON PROVIDES T H I S SOFTWARE OR OTHER INTELLECTUAL PROPERTY IN I T S AS I S CONDITION , AND ANY EXPRESS OR IMPLIED WARRANTIES , INCLUDING , BUT NOT LIMITED TO , THE IMPLIED WARRANTIES OF MERCHANTABILITY AND F I T N E S S FOR A PARTICULAR PURPOSE ARE DISCLAIMED . IN NO EVENT SHALL CARNEGIE MELLON UNIVERSITY BE L I A B L E FOR ANY DIRECT , INDIRECT , INCIDENTAL , S P E C I A L , EXEMPLARY , OR CONSEQUENTIAL DAMAGES ( INCLUDING , BUT NOT LIMITED TO , PROCUREMENT OF SUBSTITUTE GOODS OR S E R V I C E S ; LOSS OF USE , DATA , OR P R O F I T S ; OR BUSINESS INTERRUPTION ) HOWEVER CAUSED AND ON ANY THEORY OF L I A B I L I T Y , WHETHER IN CONTRACT , S T R I C T L I A B I L I T Y , OR TORT ( INCLUDING NEGLIGENCE OR OTHERWISE ) ARISING IN ANY WAY OUT OF THE USE OF T H I S SOFTWARE OR INTELLECTUAL PROPERTY , EVEN I F ADVISED OF THE P O S S I B I L I T Y OF SUCH DAMAGE . C a r n e g i e Mellon e n c o u r a ge s ( but does not r e q u i r e ) u s e r s o f t h i s s o f t w a r e o r i n t e l l e c t u a l p r o p e r t y t o r e t u r n any improvements o r e x t e n s i o n s t h a t t h e y make , and t o gr a n t C a r n e g i e Mellon t h e r i g h t s t o r e d i s t r i b u t e t h e s e changes w i t h o u t encumbrance . The AODV code d e v e l o p e d by t h e CMU/MONARCH group was o p t i m i z e d and tuned by Samir Das and Mahesh Marina , U n i v e r s i t y o f C i n c i n n a t i . The work was p a r t i a l l y done i n Sun M i c r o s y s t e m s . # # P r o j e c t : S e m e s t e r T h e s i s S S 06: # E v a l u a t i o n o f s c h e d u l i n g methods o v e r # m u l t i p a t h r o u t i n g i n w i r e l e s s m o b i l e Ad Hoc n e t w o r k s # # A u t h o r s : R e gu l a Goenner , Dominik Schatzmann # # # Date : J u l y 2006 # # The code has been m o d i e f i e d by R . Goenner and D . Schatzmann , # m o d i f i c a t i o n s a r e i n d i c a t e d with t h e tag / / [ s c h e d u l i n g ] # and t h e y can be a c t i v a t e d by u s i n g # d e f i n e SA_CHANGE # / #i n c l u d e < iostream > #i n c l u d e <random . h> #i n c l u d e < aodv / a o d v _ r t a b l e . h> / /# i n c l u d e <cmu/ aodv / aodv . h> #d e f i n e NOW Sched ul er : : i n s t a n c e ( ) . c l o c k ( ) / The R o u t i n g T a b l e / aodv_rt_entry : : aodv_rt_entry ( ) { int i ; rt_req_timeout = 0.0; r t _r eq_cnt = 0;

98

A.1. C++

r t _ d s t = 0; r t _ s eq no = 0 ; rt_last_hop_count = INFINITY2 ; # i f n d e f AOMDV r t _ ho p s = I N F I N I T Y 2 ; r t _ nex t ho p = 0 ; #e l s e / / AOMDV rt_advertised_hops = INFINITY2 ; L I S T _ I N I T (& r t _ p a t h _ l i s t ) ; r t _ hi g hes t _ s eq n o _ h e a r d = 0 ; rt_num_paths_ = 0 ; #e n d i f / / AOMDV / / CHANGE rt_error = false ; / / CHANGE L I S T _ I N I T (& r t _ p c l i s t ) ; rt_expire = 0.0; r t _ f l a g s = RTF_DOWN ;

f o r ( i =0; i < MAX_HISTORY ; i ++) { rt_disc_latency [ i ] = 0.0; } his t _indx = 0; r t _ r e q _ l a s t _ t t l = 0; L I S T _ I N I T (& r t _ n b l i s t ) ; / / [ s c h e d u l i n g ] # i f d e f SA_CHANGE t x _ r x _ i d = INT_MAX ; #e n d i f / / [ s c h e d u l i n g ] end };

// i n i t the d e s t i n a t i o n

aodv_rt_entry : : ~ aodv_rt_entry ( ) { AODV_Neighbor nb ; w hi l e ( ( nb = r t _ n b l i s t . l h _ f i r s t ) ) { LIST_REMOVE ( nb , n b _ l i n k ) ; d e l e t e nb ; } # i f d e f AOMDV AODV_Path path ; w hi l e ( ( path = r t _ p a t h _ l i s t . l h _ f i r s t ) ) { LIST_REMOVE ( path , p a t h _ l i n k ) ; d e l e t e path ; } #e n d i f / / AOMDV AODV_Precursor pc ; w hi l e ( ( pc = r t _ p c l i s t . l h _ f i r s t ) ) { LIST_REMOVE ( pc , p c _ l i n k ) ;

99

A.1. C++

d e l e t e pc ; } }

v o i d a o d v _ r t _ e n t r y : : n b _ i n s e r t ( ns ad d r _ t i d ) { AODV_Neighbor nb = new AODV_Neighbor ( i d ) ; a s s e r t ( nb ) ; nb>nb _ ex p i r e = 0 ; LIST_INSERT_HEAD (& r t _ n b l i s t , nb , n b _ l i n k ) ; }

AODV_Neighbor a o d v _ r t _ e n t r y : : nb_lookup ( ns ad d r _ t i d ) { AODV_Neighbor nb = r t _ n b l i s t . l h _ f i r s t ; f o r ( ; nb ; nb = nb>n b _ l i n k . l e _ n e x t ) { i f ( nb>nb_addr == i d ) b r eak ; } r e t u r n nb ; } # i f d e f AOMDV AODV_Path a o d v _ r t _ e n t r y : : p a t h _ i n s e r t ( ns ad d r _ t nexthop , u _ i n t 1 6 _ t hopcount , double ex p i r e_ t i m e , ns ad d r _ t l a s t h o p ) { AODV_Path path = new AODV_Path ( nexthop , hopcount , ex p i r e_ t i m e , l a s t h o p ) ; a s s e r t ( path ) ; # i f d e f DEBUG f p r i n t f ( s t d e r r , "%s : (%d \ t%d ) \ n " , __FUNCTION__ , path>nexthop , path >hopcount ) ; #e n d i f / / DEBUG / I n s e r t path a t t h e end o f t h e l i s t / AODV_Path p = r t _ p a t h _ l i s t . l h _ f i r s t ; if (p) { f o r ( ; p>p a t h _ l i n k . l e _ n e x t ; p = p> p a t h _ l i n k . l e _ n e x t ) / Do n o t h i n g / ; L I ST _ I NSE R T _ AF T E R ( p , path , p a t h _ l i n k ) ; } else { LIST_INSERT_HEAD (& r t _ p a t h _ l i s t , path , p a t h _ l i n k ) ; } rt_num_paths_ += 1 ; / / [ s c h e d u l i n g ] # i f d e f SA_CHANGE s ched _ cal c_ w e i g h t s ( ) ; #e n d i f / / [ s c h e d u l i n g ] end r e t u r n path ; } AODV_Path a o d v _ r t _ e n t r y : : path_lookup ( ns ad d r _ t i d ) {

100

A.1. C++

AODV_Path path = r t _ p a t h _ l i s t . l h _ f i r s t ; f o r ( ; path ; path = path>p a t h _ l i n k . l e _ n e x t ) { i f ( path>nexthop == i d ) r e t u r n path ; } r e t u r n NULL ; } AODV_Path a o d v _ r t _ e n t r y : : d i s j o i n t _ p a t h _ l o o k u p ( ns ad d r _ t nexthop , ns ad d r _ t l a s t h o p ) { AODV_Path path = r t _ p a t h _ l i s t . l h _ f i r s t ; f o r ( ; path ; path = path>p a t h _ l i n k . l e _ n e x t ) { i f ( ( path>nexthop == nexthop ) && ( path >l a s t h o p == l a s t h o p ) ) r e t u r n path ; } r e t u r n NULL ; } / R e t u r n s t r u e i f no path e x i s t s ( f o r t h i s r o u t e e n t r y ) which has nexthop as n e x t hop o r l a s t h o p as l a s t hop . / b o o l a o d v _ r t _ e n t r y : : n e w _ d i s j o i n t _ p a t h ( ns ad d r _ t nexthop , ns ad d r _ t l a s t h o p ) { AODV_Path path = r t _ p a t h _ l i s t . l h _ f i r s t ; f o r ( ; path ; path = path>p a t h _ l i n k . l e _ n e x t ) { i f ( ( path>nexthop == nexthop ) | | ( path >l a s t h o p == l a s t h o p ) ) return f al s e ; } return true ; }

AODV_Path a o d v _ r t _ e n t r y : : p at h_ l o o kup _ l as t ho p ( ns ad d r _ t i d ) { AODV_Path path = r t _ p a t h _ l i s t . l h _ f i r s t ; f o r ( ; path ; path = path>p a t h _ l i n k . l e _ n e x t ) { i f ( path>l a s t h o p == i d ) r e t u r n path ; } r e t u r n NULL ; }

v o i d a o d v _ r t _ e n t r y : : p a t h _ d e l e t e ( ns ad d r _ t i d ) { AODV_Path path = r t _ p a t h _ l i s t . l h _ f i r s t ; f o r ( ; path ; path = path>p a t h _ l i n k . l e _ n e x t ) { i f ( path>nexthop == i d ) { LIST_REMOVE ( path , p a t h _ l i n k ) ; d e l e t e path ; rt_num_paths_ = 1 ; b r eak ; } }

101

A.1. C++

/ / [ s c h e d u l i n g ] # i f d e f SA_CHANGE s ched _ cal c_ w e i g h t s ( ) ; #e n d i f / / [ s c h e d u l i n g ] end } void aodv_rt_entry : : path_delete ( void ) { AODV_Path path ; w hi l e ( ( path = r t _ p a t h _ l i s t . l h _ f i r s t ) ) { LIST_REMOVE ( path , p a t h _ l i n k ) ; d e l e t e path ; } rt_num_paths_ = 0 ; / / [ s c h e d u l i n g ] # i f d e f SA_CHANGE s ched _ cal c_ w e i g h t s ( ) ; #e n d i f / / [ s c h e d u l i n g ] end } void aodv_rt_entry : : path_delete_longest ( void ) { AODV_Path p = r t _ p a t h _ l i s t . l h _ f i r s t ; AODV_Path path = NULL ; u _ i n t 1 6 _ t max_hopcount = 0 ; f o r ( ; p ; p = p>p a t h _ l i n k . l e _ n e x t ) { i f ( p>hopcount > max_hopcount ) { a s s e r t ( p>hopcount ! = I N F I N I T Y 2 ) ; path = p ; max_hopcount = p>hopcount ; } } i f ( path ) { LIST_REMOVE ( path , p a t h _ l i n k ) ; d e l e t e path ; rt_num_paths_ = 1 ; } / / [ s c h e d u l i n g ] # i f d e f SA_CHANGE s ched _ cal c_ w e i g h t s ( ) ; #e n d i f / / [ s c h e d u l i n g ] end } b o o l a o d v _ r t _ e n t r y : : path_empty ( v o i d ) { AODV_Path path ; if { ( ( path = r t _ p a t h _ l i s t . l h _ f i r s t ) ) a s s e r t ( rt_num_paths_ > 0 ) ; return f al s e ; } else { a s s e r t ( rt_num_paths_ == 0 ) ; return true ; }

102

A.1. C++

} AODV_Path a o d v _ r t _ e n t r y : : path_findMinHop ( v o i d ) { AODV_Path p = r t _ p a t h _ l i s t . l h _ f i r s t ; AODV_Path path = NULL ; u _ i n t 1 6 _ t min_hopcount = 0 x f f f f ; f o r ( ; p ; p = p>p a t h _ l i n k . l e _ n e x t ) { i f ( p>hopcount < min_hopcount ) { path = p ; min_hopcount = p>hopcount ; } } r e t u r n path ; } / / [ s c h e d u l i n g ] # i f d e f SA_CHANGE AODV_Path a o d v _ r t _ e n t r y : : p a t h _ f i n d ( ns ad d r _ t s r c , ns ad d r _ t i nd ex ) #else AODV_Path a o d v _ r t _ e n t r y : : p a t h _ f i n d ( ) #e n d i f { AODV_Path p ; // i f t h i s i s the sender # i f d e f SA_CHANGE i f ( i nd ex == s r c ) p = sched_get_path ( ) ; / / do not s c h e d u l e i n i n t e r m e d i a t e nodes else #e n d i f p = rt_path_list . lh_first ; / / t h e s c h e d u l e r r e t u r n s t h e f i r s t path o f t h e l i s t but t h i s e n t r y can change , / / as t h e i n f o r m a t i o n ( e . g r t t ) depend on t h e path i t would make s e n s e t o s t o r e / / t h e i d o f t h e n e x t hop t h a t was used . I f t h i s path does no l o n g e r e x i s t a new / / p i n g would be r e q u i r e d and t h i s s h o u l d be i n d i c a t e d t o t h e s o u r c e . # i f d e f SA_CHANGE / / we have t o r e s e t t h e path t i m e o u t p>e x p i r e = NOW + ACTIVE_PATH_TIMEOUT ; #e n d i f return p ; } # i f d e f SA_CHANGE v o i d a o d v _ r t _ e n t r y : : s ched _ cal c _ w e i g h t s ( ) { / / c a l c u l a t e t h e w e i gh t i n g v a l u e s a c c o r d i n g t o a c e r t a i n c r i t e r i a AODV_Path p = rt_path_list . lh_first ; int total_value = 0; / / use t h i s t o f i n d t h e sum o f t h e v a l u e s i nt prev_value = 0; int t ota l_diff = 0; i n t num_paths = 0; i n t t o t al _ ho p co unt = 0 ; f o r ( ; p ; p = p>p a t h _ l i n k . l e _ n e x t ) { num_paths + + ; t o t al _ ho p co unt += p>hopcount ; } s w i t ch ( s ched _ t y p e ) { cas e 0 : { / / AOMDV

103

A.1. C++

p = rt_path_list . l h _ f i r s t ; // reset i n t min = INT_MAX ; i n t idx = 0; / / s e t t h e cumulated hopcounts i n t h e w e i gh t s a r r a y f o r ( i n t l = 0 ; l < num_paths ; l ++) { i f ( p>hopcount < min ) { min = p>hopcount ; idx = l ; } p = p> p a t h _ l i n k . l e _ n e x t ; } f o r ( i n t m = 0 ; m < num_paths ; m++) { i f (m >= i d x ) { weights [m]= INT_MAX ; } else { weights [m] = 0 ; } } } b r eak ; / / cas e 1 : { / / RR t o t a l _ v a l u e = num_paths ; f o r ( i n t i =0; i < num_paths ; i ++) { weights [ i ] = ( INT_MAX 1 ) / t o t a l _ v a l u e + p r e v _ v a l u e ; p r e v _ v a l u e = weights [ i ] ; } } b r eak ; / / cas e 2 : { / / WRR , t h e s h o r t e s t path i s used most o f t e n p = rt_path_list . l h _ f i r s t ; // reset t o t a l _ d i f f = ( num_paths 1) t o t al _ ho p co unt ; f o r ( i n t i =0; i < num_paths ; i ++) { i f ( t o t a l _ d i f f == 0 ) { i f ( num_paths == 1 ) { weights [ i ] = INT_MAX ; } e l s e cout << " e r r o r , check WRR i n a o d v _ r t a b l e " ; } else { weights [ i ] = i n t ( INT_MAX ( double ( ( t o t al _ ho p co unt p>hopcount ) / double ( t o t a l _ d i f f ) ) ) + p r e v _ v a l u e ) ; p r e v _ v a l u e = weights [ i ] ; p = p>p a t h _ l i n k . l e _ n e x t ; } } } b r eak ; / / cas e 3 : { / / SN , s e l e c t N path and WRR

104

A.1. C++

/ i f you want t o use o n l y some o f t h e path , h e r e a l l path with a hopcount t h a t i s l a r g e r than 20% o f t h e mean a r e not used / double mean ; mean = t o t al _ ho p co unt / double ( num_paths ) ; i nt threshold ; t h r e s h o l d = i n t ( 1 . 2 mean ) ; p = rt_path_list . l h _ f i r s t ; // reset t o t a l _ v a l u e = 0; i nt prev_value ; prev_value = 0; / / s e t t h e cumulated hopcounts i n t h e w e i gh t s a r r a y f o r ( i n t l = 0 ; l < num_paths ; l ++) { i f ( p>hopcount <= t h r e s h o l d ) { t o t a l _ v a l u e += p>hopcount ; weights [ l ] = p>hopcount + p r e v _ v a l u e ; p r e v _ v a l u e = weights [ l ] ; } else { weights [ l ] = 0 ; } p = p>p a t h _ l i n k . l e _ n e x t ; } / / c a l c u l a t e t h e w e i gh t s ( d i v by t o t a l _ v a l u e and mult by INT_MAX f o r ( i n t m = 0 ; m < num_paths ; m++) { i f ( t o t a l _ v a l u e ! = 0) { weights [m] = i n t ( double ( ( weights [m] / double ( t o t a l _ v a l u e ) ) INT_MAX ) ) ; } else { weights [m] = INT_MAX ; } } } b r eak ; / / cas e 4 : { / / WRR with t h e r t t p = rt_path_list . l h _ f i r s t ; // reset double t o t a l _ r t t = 0 . 0 ; f o r ( i n t i =0; i <num_paths ; i ++) { t o t a l _ r t t += p> r t t ; p = p>p a t h _ l i n k . l e _ n e x t ; } double t o t a l _ r t t _ d i f f = ( num_paths 1 ) t o t a l _ r t t ; p = rt_path_list . lh_first ; f o r ( i n t j = 0 ; j < num_paths ; j ++) { i f ( t o t a l _ d i f f == 0 && num_paths == 1 ) { weights [ j ] = INT_MAX ; } else {

105

A.1. C++

weights [ j ] = i n t ( INT_MAX ( double ( ( t o t a l _ r t t p> r t t ) / t o t a l _ r t t _ d i f f ) ) + p r e v _ v a l u e ) ; p r e v _ v a l u e = weights [ j ] ; p = p>p a t h _ l i n k . l e _ n e x t ; } } } b r eak ; / / cas e 5 : { / / s e l e c t t h e path with l o w e s t number o f n e i g h b o u r s p = rt_path_list . l h _ f i r s t ; // reset i n t min_neigh = INT_MAX ; f o r ( i n t i = 0 ; i < num_paths ; i ++) { i f ( p>nr _ nei g h < min_neigh ) min_neigh = p>nr _ nei g h ; p = p> p a t h _ l i n k . l e _ n e x t ; } p = rt_path_list . lh_first ; i n t f l ag _ f o und = 0 ; f o r ( i n t j = 0 ; j < num_paths ; j ++) { i f ( f l ag _ f o und == 0) { i f ( p>nr _ nei g h = min_neigh ) { weights [ j ] = INT_MAX ; f l ag _ f o und = 1 ; } else { weights [ j ] = 0 ; } } else { weights [ j ] = INT_MAX ; } p = p> p a t h _ l i n k . l e _ n e x t ; } } b r eak ; / / default : cout << " T h i s s c h e d u l e r does not e x i s t ! \ n " ; b r eak ; / / } / / # i f d e f SA_DEBUG path_dumptable ( ) ; i f ( num_paths > 0) { cout << " weights | " ; f o r ( i n t i = 0 ; i < num_paths ; i ++) { cout << " " << weights [ i ] << " | " ; } cout << " \ n " ; cout << " hopcount | " ; p = rt_path_list . lh_first ; f o r ( i n t i = 0 ; i < num_paths ; i ++)

106

A.1. C++

{ cout << " " << p>hopcount << " | " ; p = p> p a t h _ l i n k . l e _ n e x t ; } cout << " \ n " ; cout << " r t t |"; p = rt_path_list . lh_first ; f o r ( i n t i = 0 ; i < num_paths ; i ++) { cout << " " << p> r t t << " | " ; p = p> p a t h _ l i n k . l e _ n e x t ; } cout << " \ n " ; cout << " next hop | " ; p = rt_path_list . lh_first ; f o r ( i n t i = 0 ; i < num_paths ; i ++) { cout << " " << p>nexthop << " | " ; p = p> p a t h _ l i n k . l e _ n e x t ; } cout << " \ n " ; cout << " nei g hs | " ; p = rt_path_list . lh_first ; f o r ( i n t i = 0 ; i < num_paths ; i ++) { cout << " " << p>nr _ nei g h << " | " ; p = p> p a t h _ l i n k . l e _ n e x t ; } cout << " \ n " ; } #e n d i f / / }

AODV_Path a o d v _ r t _ e n t r y : : sched_get_path ( ) { / / r o l l t h e d i c e and r e t u r n t h e path AODV_Path p = r t _ p a t h _ l i s t . l h _ f i r s t ; i n t num_paths = 0 ; f o r ( ; p ; p = p>p a t h _ l i n k . l e _ n e x t ) / / count t h e number o f p a t h s { num_paths + + ; } / / c r e a t e v a l u e s i n t h e range o f 0 t o INT_MAX1 i n t random = i n t ( Random : : uniform ( INT_MAX ) ) % INT_MAX ; p = rt_path_list . lh_first ; // reset p i n t i = 0; w hi l e ( i < num_paths ) { i f ( weights [ i ] >= random ) { b r eak ; } else { i ++; p = p> p a t h _ l i n k . l e _ n e x t ; } } return p ; } / / [ s c h e d u l i n g ] end

107

A.1. C++

#e n d i f u _ i n t 1 6 _ t a o d v _ r t _ e n t r y : : path_get_max_hopcount ( v o i d ) { AODV_Path path = r t _ p a t h _ l i s t . l h _ f i r s t ; u _ i n t 1 6 _ t max_hopcount = 0 ; f o r ( ; path ; path = path> p a t h _ l i n k . l e _ n e x t ) { i f ( path>hopcount > max_hopcount ) { max_hopcount = path >hopcount ; } } i f ( max_hopcount == 0) r e t u r n I N F I N I T Y 2 ; e l s e r e t u r n max_hopcount ; } u _ i n t 1 6 _ t a o d v _ r t _ e n t r y : : path_get_min_hopcount ( v o i d ) { AODV_Path path = r t _ p a t h _ l i s t . l h _ f i r s t ; u _ i n t 1 6 _ t min_hopcount = I N F I N I T Y 2 ; f o r ( ; path ; path = path> p a t h _ l i n k . l e _ n e x t ) { i f ( path>hopcount < min_hopcount ) { min_hopcount = path >hopcount ; } } r e t u r n min_hopcount ; } double a o d v _ r t _ e n t r y : : p at h_ g et _ m ax _ ex p i r at i o n_ t i m e ( v o i d ) { AODV_Path path = r t _ p a t h _ l i s t . l h _ f i r s t ; double max_expire_time = 0 ; f o r ( ; path ; path = path> p a t h _ l i n k . l e _ n e x t ) { i f ( path>e x p i r e > max_expire_time ) { max_expire_time = path> e x p i r e ; } } r e t u r n max_expire_time ; } v o i d a o d v _ r t _ e n t r y : : path_purge ( v o i d ) { double now = Sched ul er : : i n s t a n c e ( ) . c l o c k ( ) ; b o o l cond ; do { AODV_Path path = r t _ p a t h _ l i s t . l h _ f i r s t ; cond = f a l s e ; f o r ( ; path ; path = path >p a t h _ l i n k . l e _ n e x t ) { i f ( path> e x p i r e < now ) { cond = t r u e ; LIST_REMOVE ( path , p a t h _ l i n k ) ; d e l e t e path ; rt_num_paths_ = 1 ; / / [ s c h e d u l i n g ] # i f d e f SA_CHANGE

108

A.1. C++

s ched _ cal c _ w e i g h t s ( ) ; #e n d i f / / [ s c h e d u l i n g ] end b r eak ; } } } w hi l e ( cond ) ; } #e n d i f / / AOMDV v o i d a o d v _ r t _ e n t r y : : p c _ i n s e r t ( ns ad d r _ t i d ) { i f ( pc_lookup ( i d ) == NULL ) { AODV_Precursor pc = new AODV_Precursor ( i d ) ; a s s e r t ( pc ) ; LIST_INSERT_HEAD (& r t _ p c l i s t , pc , p c _ l i n k ) ; } }

AODV_Precursor a o d v _ r t _ e n t r y : : pc_lookup ( ns ad d r _ t i d ) { AODV_Precursor pc = r t _ p c l i s t . l h _ f i r s t ; f o r ( ; pc ; pc = pc> p c _ l i n k . l e _ n e x t ) { i f ( pc>pc_addr == i d ) r e t u r n pc ; } r e t u r n NULL ; } v o i d a o d v _ r t _ e n t r y : : p c _ d e l e t e ( ns ad d r _ t i d ) { AODV_Precursor pc = r t _ p c l i s t . l h _ f i r s t ; f o r ( ; pc ; pc = pc> p c _ l i n k . l e _ n e x t ) { i f ( pc>pc_addr == i d ) { LIST_REMOVE ( pc , p c _ l i n k ) ; d e l e t e pc ; b r eak ; } } } void aodv_rt_entry : : pc_delete ( void ) { AODV_Precursor pc ; w hi l e ( ( pc = r t _ p c l i s t . l h _ f i r s t ) ) { LIST_REMOVE ( pc , p c _ l i n k ) ; d e l e t e pc ; } } b o o l a o d v _ r t _ e n t r y : : pc_empty ( v o i d ) { AODV_Precursor pc ; i f ( ( pc = r t _ p c l i s t . l h _ f i r s t ) ) r e t u r n f a l s e ;

109

A.1. C++

else return true ; } / The R o u t i n g T a b l e / a o d v _ r t _ e n t r y a o d v _ r t a b l e : : r t _ l o o k u p ( ns ad d r _ t i d ) { a o d v _ r t _ e n t r y r t = r t head . l h _ f i r s t ; f o r ( ; r t ; r t = r t > r t _ l i n k . l e _ n e x t ) { i f ( r t > r t _ d s t == i d ) b r eak ; } return r t ; } v o i d a o d v _ r t a b l e : : r t _ d e l e t e ( ns ad d r _ t i d ) { aodv_rt_entry r t = rt_lookup ( id ) ; if ( rt ) { LIST_REMOVE ( r t , r t _ l i n k ) ; delete r t ; } } a o d v _ r t _ e n t r y a o d v _ r t a b l e : : r t _ ad d ( ns ad d r _ t i d ) { aodv_rt_entry r t ; a s s e r t ( r t _ l o o k u p ( i d ) == 0 ) ; r t = new a o d v _ r t _ e n t r y ; assert ( r t ) ; r t > r t _ d s t = i d ; LIST_INSERT_HEAD (& rthead , r t , r t _ l i n k ) ; / / [ s c h e d u l i n g ] # i f d e f SA_CHANGE r t >s ched _ t y p e = s ched _ t y p e ; r t >aomdv_max_paths_ = aomdv_max_paths_ ; r t >weights = new i n t [ aomdv_max_paths_ ] ; r t >s ched _ cal c _ w e i g h t s ( ) ; #e n d i f / / [ s c h e d u l i n g ] end return r t ; } v o i d a o d v _ r t a b l e : : rt_dumptable ( ) { a o d v _ r t _ e n t r y r t = r t head . l h _ f i r s t ; p r i n t f ( "\n " ) ; w hi l e ( r t ! = 0) { p r i n t f ( "%6s %6s " , " Dest " , " Seq#" ) ; # i f n d e f AOMDV p r i n t f ( "%6s %6s \ n " , " Hops " , " Nxthop " ) ; #e l s e p r i n t f ( "%6s %6s %6s %6s \ n " , " Advhop " , " Nxthop " , " Hopcnt " , " L s t ho p " ) ; #e n d i f / / AOMDV p r i n t f ( "%6d %6d " , r t >r t _ d s t , r t >r t _ s eq no ) ; # i f n d e f AOMDV p r i n t f ( "%6d %6d \ n " , r t >rt_hops , r t >r t _ nex t ho p ) ; #e l s e

110

A.1. C++

p r i n t f ( "%6d \ n " , r t >r t _ a d v e r t i s e d _ h o p s ) ; / P r i n t path l i s t f o r t h i s r o u t e e n t r y . / AODV_Path paths = r t > r t _ p a t h _ l i s t . l h _ f i r s t ; paths >p r i n t P a t h s ( ) ; #e n d i f / / AOMDV p r i n t f ( " \n " ) ; r t = r t > r t _ l i n k . l e _ n e x t ; } } bool aodv_rtable : : r t _has _act i ve_r o ut e ( ) { / Go through l i s t o f r o u t e e n t r i e s t o s e e i f t h e r e e x i s t s any v a l i d r o u t e e n t r y / a o d v _ r t _ e n t r y r t = r t head . l h _ f i r s t ; w hi l e ( r t ! = 0) { i f ( r t > r t _ f l a g s == RTF_UP ) return true ; r t = r t > r t _ l i n k . l e _ n e x t ; } return f al s e ; }

Listing A.4: aodv_rtable.cc

111

A.1. C++

A.1.5. aodv_packet.h
/ Mode : C + + ; cb a s i c o f f s e t : 4 ; tabwidth : 4 ; i n d e n ttabsmode : t / / C o p y r i g h t ( c ) 1 9 9 7 , 1998 C a r n e g i e Mellon U n i v e r s i t y . A l l R i g h t s Reserved . P e r m i s s i o n t o use , copy , modify , and d i s t r i b u t e t h i s s o f t w a r e and i t s documentation i s h e r e b y gr a n t e d ( i n c l u d i n g f o r commercial o r f o r p r o f i t use ) , p r o v i d e d t h a t both t h e c o p y r i g h t n o t i c e and t h i s p e r m i s s i o n n o t i c e appear i n a l l c o p i e s o f t h e s o f t w a r e , d e r i v a t i v e works , o r m o d i f i e d v e r s i o n s , and any p o r t i o n s t h e r e o f , and t h a t both n o t i c e s appear i n s u p p o r t i n g documentation , and t h a t c r e d i t i s g i v e n t o C a r n e g i e Mellon U n i v e r s i t y i n a l l p u b l i c a t i o n s r e p o r t i n g on d i r e c t o r i n d i r e c t use o f t h i s code o r i t s d e r i v a t i v e s . ALL CODE , SOFTWARE , PROTOCOLS , AND ARCHITECTURES DEVELOPED BY THE CMU MONARCH PROJECT ARE EXPERIMENTAL AND ARE KNOWN TO HAVE BUGS , SOME OF WHICH MAY HAVE SERIOUS CONSEQUENCES . CARNEGIE MELLON PROVIDES T H I S SOFTWARE OR OTHER INTELLECTUAL PROPERTY IN I T S AS I S CONDITION , AND ANY EXPRESS OR IMPLIED WARRANTIES , INCLUDING , BUT NOT LIMITED TO , THE IMPLIED WARRANTIES OF MERCHANTABILITY AND F I T N E S S FOR A PARTICULAR PURPOSE ARE DISCLAIMED . IN NO EVENT SHALL CARNEGIE MELLON UNIVERSITY BE L I A B L E FOR ANY DIRECT , INDIRECT , INCIDENTAL , S P E C I A L , EXEMPLARY , OR CONSEQUENTIAL DAMAGES ( INCLUDING , BUT NOT LIMITED TO , PROCUREMENT OF SUBSTITUTE GOODS OR S E R V I C E S ; LOSS OF USE , DATA , OR P R O F I T S ; OR BUSINESS INTERRUPTION ) HOWEVER CAUSED AND ON ANY THEORY OF L I A B I L I T Y , WHETHER IN CONTRACT , S T R I C T L I A B I L I T Y , OR TORT ( INCLUDING NEGLIGENCE OR OTHERWISE ) ARISING IN ANY WAY OUT OF THE USE OF T H I S SOFTWARE OR INTELLECTUAL PROPERTY , EVEN I F ADVISED OF THE P O S S I B I L I T Y OF SUCH DAMAGE . C a r n e g i e Mellon e n c o u r a ge s ( but does not r e q u i r e ) u s e r s o f t h i s s o f t w a r e o r i n t e l l e c t u a l p r o p e r t y t o r e t u r n any improvements o r e x t e n s i o n s t h a t t h e y make , and t o gr a n t C a r n e g i e Mellon t h e r i g h t s t o r e d i s t r i b u t e t h e s e changes w i t h o u t encumbrance . The AODV code d e v e l o p e d by t h e CMU/MONARCH group was o p t i m i z e d and tuned by Samir Das and Mahesh Marina , U n i v e r s i t y o f C i n c i n n a t i . The work was p a r t i a l l y done i n Sun M i c r o s y s t e m s . # # P r o j e c t : S e m e s t e r T h e s i s S S 06: # E v a l u a t i o n o f s c h e d u l i n g methods o v e r # m u l t i p a t h r o u t i n g i n w i r e l e s s m o b i l e Ad Hoc n e t w o r k s # # A u t h o r s : R e gu l a Goenner , Dominik Schatzmann # # # Date : J u l y 2006 # # The code has been m o d i e f i e d by R . Goenner and D . Schatzmann , # m o d i f i c a t i o n s a r e i n d i c a t e d with t h e tag / / [ s c h e d u l i n g ] # and t h e y can be a c t i v a t e d by u s i n g # d e f i n e SA_CHANGE # / # i f n d e f __aodv_packet_h__ #d e f i n e __aodv_packet_h__ #d e f i n e AODV_MAX_ERRORS 100

/ ===================================================================== P a c k e t Formats . . . ===================================================================== / #d e f i n e AODVTYPE_HELLO 0x01 #d e f i n e AODVTYPE_RREQ 0x02 #d e f i n e AODVTYPE_RREP 0x04 #d e f i n e AODVTYPE_RERR 0x08 #d e f i n e AODVTYPE_RREP_ACK 0x10 #d e f i n e AODVTYPE_PING 0x06 #d e f i n e AODVTYPE_INFO 0x07

112

A.1. C++

/ AODV R o u t i n g P r o t o c o l Header Macros / #d e f i n e HDR_AODV ( p ) ( ( s t r u c t hdr_aodv ) hdr_aodv : : a c c e s s ( p ) ) #d e f i n e HDR_AODV_REQUEST ( p ) ( ( s t r u c t hd r _ ao d v _ r eq ues t ) hdr_aodv : : a c c e s s ( p ) ) #d e f i n e HDR_AODV_REPLY( p ) ( ( s t r u c t hd r _ ao d v _ r ep l y ) hdr_aodv : : a c c e s s ( p ) ) / / [ s c h e d u l i n g ] # i f d e f SA_CHANGE #d e f i n e HDR_AODV_PING ( p ) ( ( s t r u c t hdr_aodv_ping ) hdr_aodv : : a c c e s s ( p ) ) #d e f i n e HDR_AODV_INFO( p ) ( ( s t r u c t hd r _ ao d v _ i nf o ) hdr_aodv : : a c c e s s ( p ) ) #e n d i f / / [ s c h e d u l i n g ] end #d e f i n e HDR_AODV_ERROR ( p ) ( ( s t r u c t h d r _ a o d v _ e r r o r ) hdr_aodv : : a c c e s s ( p ) ) #d e f i n e HDR_AODV_RREP_ACK ( p ) ( ( s t r u c t hd r _ ao d v _ r r ep _ ack ) hdr_aodv : : a c c e s s ( p ) ) / G e n e r a l AODV Header s h a r e d by a l l f o r m a t s / s t r u c t hdr_aodv { u _ i n t 8 _ t ah_type ; / / Header a c c e s s methods static int offset_ ; / / r e q u i r e d by PacketHeaderManager i n l i n e s t a t i c i n t& o f f s e t ( ) { r e t u r n o f f s e t _ ; } i n l i n e s t a t i c hdr_aodv a c c e s s ( co ns t Packet p ) { r e t u r n ( hdr_aodv ) p>a c c e s s ( o f f s e t _ ) ; } }; s t r u c t hd r _ ao d v _ r eq ues t { u_int8_t rq_type ; u_int8_t reserved [ 2 ] ; u_int8_t rq_hop_count ; u_int32_t rq_bcast_id ; ns ad d r _ t u_int32_t ns ad d r _ t u_int32_t rq_dst ; r q _ d s t _ s eq no ; rq_src ; r q _ s r c_ s eq no ;

/ / P a c k e t Type / / Hop Count / / B r o a d c a s t ID // // // // Destination I P Address D e s t i n a t i o n Sequence Number Source I P Address S o u r c e Sequence Number

double rq_timestamp ; / / when REQUEST s e n t ; / / used t o compute r o u t e d i s c o v e r y l a t e n c y # i f d e f AOMDV ns ad d r _ t rq_first_hop ; #e n d i f / / AOMDV

/ / F i r s t Hop t a k e n by t h e RREQ

/ / T h i s d e f i n e t u r n s on g r a t u i t o u s r e p l i e s / / s e e aodv . c c f o r i m p l e m e n t a t i on c o n t r i b u t e d by / / Anant U t g i k a r , 0 9 / 1 6 / 0 2 . / /# d e f i n e RREQ_GRAT_RREP 0x80 inline int size ( ) { i n t sz = 0; s z = 7 s i z e o f ( u _ i n t 3 2 _ t ) ; # i f d e f AOMDV s z += s i z e o f ( ns ad d r _ t ) ; #e n d i f / / AOMDV a s s e r t ( s z >= 0 ) ; return sz ; } };

// rq_first_hop

113

A.1. C++

/ / [ s c h e d u l i n g ] # i f d e f SA_CHANGE s t r u c t hdr_aodv_ping { u_int8_t type ; ns ad d r _ t src ; ns ad d r _ t dst ; ns ad d r _ t first_hop ; ns ad d r _ t last_hop ; ns ad d r _ t next_hop ; u_int8_t hop_count ; int ping_reply_flag ; u_int8_t nr _ nei g h ; inline int size ( ) { i n t sz = 0; s z = 5 s i z e o f ( ns ad d r _ t ) ; s z += 3 s i z e o f ( u _ i n t 8 _ t ) ; s z += s i z e o f ( i n t ) ; a s s e r t ( s z >= 0 ) ; return sz ; } }; s t r u c t hd r _ ao d v _ i nf o { u_int8_t type ; ns ad d r _ t src ; ns ad d r _ t dst ; ns ad d r _ t next_hop ; ns ad d r _ t first_hop ; ns ad d r _ t last_hop ; u_int8_t hop_count ; u_int8_t path_count ; double rtt ; int action ; }; #e n d i f / / [ s c h e d u l i n g ] end s t r u c t hd r _ ao d v _ r ep l y { u_int8_t rp_type ; u_int8_t reserved [ 2 ] ; u_int8_t rp_hop_count ; ns ad d r _ t rp_dst ; u_int32_t r p _ d s t _ s eq no ; ns ad d r _ t rp_src ; double rp_lifetime ;

// // // // // // // // //

packet type source I P address d es ti n a ti o n I P address f i r s t hop o f t h e r o u t e l a s t hop o f t h e r o u t e , used as i d n e x t hop hop count is this a reply ? t o t a l number o f n e i gh along t h e r o u t e

/ / P a c k e t Type // Source I P Address // Destination I P Address

/ / Hop Count

/ / P a c k e t Type // // // // // Hop Count Destination I P Address D e s t i n a t i o n Sequence Number Source I P Address Lifetime

double rp_timestamp ; / / when c o r r e s p o n d i n g REQ s e n t ; / / used t o compute r o u t e d i s c o v e r y l a t e n c y # i f d e f AOMDV u_int32_t rp_bcast_id ; ns ad d r _ t rp_first_hop ; #e n d i f / / AOMDV inline int size ( ) { i n t sz = 0; s z = 6 s i z e o f ( u _ i n t 3 2 _ t ) ;

/ / B r o a d c a s t ID o f t h e c o r r e s p o n d i n g RREQ

114

A.1. C++

# i f d e f AOMDV i f ( r p _ t y p e == AODVTYPE_RREP ) { s z += s i z e o f ( u _ i n t 3 2 _ t ) ; / / r p _ b c a s t _ i d s z += s i z e o f ( ns ad d r _ t ) ; / / r p _ f i r s t _ h o p } #e n d i f / / AOMDV a s s e r t ( s z >= 0 ) ; return sz ; } };

s t r uct hdr_aodv_error { u_int8_t re_type ; / / Type u_int8_t reserved [ 2 ] ; // Reserved u_int8_t DestCount ; / / DestCount / / L i s t o f Un r e a c h a b l e d e s t i n a t i o n I P a d d r e s s e s and s e q u e n c e numbers ns ad d r _ t unr eachab l e_ d s t [ AODV_MAX_ERRORS ] ; u_int32_t unr eachab l e_ d s t _ s eq no [ AODV_MAX_ERRORS ] ; inline int size ( ) { i n t sz = 0; s z = ( DestCount 2 + 1 ) s i z e o f ( u _ i n t 3 2 _ t ) ; assert ( sz ) ; return sz ; } }; s t r u c t hd r _ ao d v _ r r ep _ ack { u_int8_t rpack_type ; u_int8_t reserved ; }; // for si ze calculation union h d r _ a l l _ a o d v { hdr_aodv hd r _ ao d v _ r eq ues t hd r _ ao d v _ r ep l y hdr_aodv_error hd r _ ao d v _ r r ep _ ack }; o f headers p a c e r e s e r v a t i o n

ah ; rreq ; rrep ; rerr ; rrep_ack ;

#e n d i f / _ _ a o d v _ p a c k e t _ h_ _ /

Listing A.5: aodv_packet.h

115

A.2. Tcl

A.2. Tcl
A.2.1. aomdv.tcl
# # AOMDV:TCL F I L E TO START ANS CONFIGURE SIMULATION WITH NS # # P r o j e c t : S e m e s t e r T h e s i s S S 06 : # E v a l u a t i o n o f s c h e d u l i n g methods o v e r # m u l t i p a t h r o u t i n g i n w i r e l e s s m o b i l e Ad Hoc networks # # A u t h o r s : R e gu l a G o e n n e r , Dominik Schatzmann # # [ Tcl Script ] # # Date: J u l y 2006 # # Input: # tracefile # mobility pattern # t r a f f i c pattern # queue t y p e _ # queue l eng t h # dimension x # dimension y # number o f nodes # s i m u l a t i o n time # simulation progress # s c h ed u l er type # aomdv max number o f path # # Output: # [ none ] # # # function c a l l : set t r a c e f i l e _ set mobility_pattern_ set t r a f f i c _ p a t t e r n _ s e t queue_type_ s e t queue_length_ s e t dimension_x_ s e t dimension_y_ s e t number_of_node_ s e t sim_time_ s e t s i m _ p r o g r es s _ s e t s ched _ t y p e_ i n_ s e t aomdv_max_path_in_ puts puts puts puts puts puts puts puts puts puts puts puts puts puts puts puts puts [ lindex [ lindex [ lindex [ lindex [ lindex [ lindex [ lindex [ lindex [ lindex [ lindex [ lindex [ lindex $ ar g v 0 ] ; $ ar g v 1]; $ ar g v 2 ] ; $ ar g v 3 ] ; $ ar g v 4 ] ; $ ar g v 5 ] ; $ ar g v 6 ] ; $ ar g v 7 ] ; $ ar g v 8 ] ; $ ar g v 9 ] ; $ ar g v 1 0 ] ; $ ar g v 1 1 ] ; # # # # # # # # # # # # tracefile mobility pattern t r a f f i c pattern [ CMUPriQueue Queue / D r o p T a i l / P r i Q u e u e ] Queue l eng t h max p a c k e t l eng t h i n i f q Dimension X Dimension Y Simulation duration S i m u l a t i o n p r o g e s s = pause_time ? t y p e o f AOMDV s c h e d u l e r maximum number o f p a t h s

" TCLARGUMENTS: v i s u a l t e s t " " tracefile: " $tracefile_ " mobility pattern: " $mobility_pattern_ " t r a f f i c pattern: " $traffic_pattern_ " queue t y p e : " $queue_type_ " queue l e n g t h : " $queue_length_ " x: " $dimension_x_ " y: " $dimension_y_ "# no d es : " $number_of_node_

116

A.2. Tcl

puts puts puts puts

" sim t i m e : " $sim_time_ " sim p r o g r e s s : " $ s i m _ p r o g r es s _

#AOMDV s p e c i a l p a r a m e t e r s puts " sched t y p e : " puts $ s ched _ t y p e_ i n _ puts "max p a t h s : " puts $aomdv_max_path_in_ # t c l s c r i p t t o debug t h e ns # i n i t value i n t c l / l i b / nsdefault Phy / W i r el es s Phy Phy / W i r el es s Phy Phy / W i r el es s Phy Phy / W i r el es s Phy Phy / W i r el es s Phy Phy / W i r el es s Phy Phy / W i r el es s Phy Mac/802 _ 1 1 Mac/802 _ 1 1 Agent /AODV Agent /AODV set set set set set set set set set CPThresh_ 10 . 0 CSThresh_ 3 .08319e11 RXThresh_ 1 .49226e10 bandwidth_ 2e6 Pt _ 0.1 freq_ 2 .472e9 L_ 1 .0 b a s i c R a t e _ 2e6 d at aR at e_ 54 e6 ;# ;# ;# ;# ;# ;# ;# ;# ;# 10 dB 550m 250m outdated 1mW 2 .472GHz system l o s s 54Mps

s e t s ched _ t y p e $ s ched _ t y p e_ i n_ s e t aomdv_max_paths_ $aomdv_max_path_in_

set set set set set set set set set set set set set set set set set

val val val val val val val val val val val val val val val val val

( chan ) Channel / W i r el es s C hannel ( prop ) Pr o p ag at i o n / F r eeSp ace ( netif ) Phy / W i r el es s Phy ( mac ) Mac/802 _ 1 1 ( ifq ) $queue_type_ ( ll ) LL ( ant ) Antenna / OmniAntenna (x) $dimension_x_ (y) $dimension_y_ ( ifqlen ) $queue_length_ ( seed ) 0.0 ( adhocRouting ) AODV ( nn ) $number_of_node_ ( cp ) $traffic_pattern_ ( sc ) $mobility_pattern_ ( stop ) $sim_time_ ( progress ) $ s i m _ p r o g r es s _

; #Queue / D r o p T a i l / P r i Q u e u e

; # X dimension o f t h e topography ; # Y dimension o f t h e topography ; # max p a c k e t i n i f q

; # how many nodes a r e s i m u l a t e d

; # s i m u l a t i o n time

# ===================================================================== # Main Program # ======================================================================

# I n i t i a l i z e Global Variables # s e t s e e d o f random number g e n e r a t o r # ( we g e n e r a t e random t r a f f i c and random m o b i l i t y ) g l o b a l defaultRNG ; $defaultRNG seed 1 2 3 4 ;

# create simulator instance s e t ns_ [ new S i m u l a t o r ] # s e t u p topography o b j e c t s e t topo [ new Topography ] # c r e a t e t r a c e o b j e c t f o r ns

117

A.2. Tcl

s e t t r a c e f d [ open " | gawk f t r _ t o _ v a l . a w k | \ gawk v M_N = $number_of_node_ f v al _ t o _ s i m . aw k > $ t r a c e f i l e _ . s i m " w] $ns_ usenewtrace $ns_ t r a c e a l l $ t r a c e f d # define topology $topo l o a d _ f l a t g r i d $ v a l ( x ) $ v a l ( y ) # # C r e a t e God # s e t god_ [ creategod $ v a l ( nn ) ] # # d e f i n e how node s h o u l d be c r e a t e d # # g l o b a l node s e t t i n g s e t chan_1_ [ new $ v a l ( chan ) ] $ns_ nodeconfig adhocRouting $ v a l ( adhocRouting ) \ llType $val ( l l ) \ macType $ v a l ( mac ) \ ifqType $ v a l ( i f q ) \ ifqLen $ v a l ( i f q l e n ) \ antType $ v a l ( ant ) \ propType $ v a l ( prop ) \ phyType $ v a l ( n e t i f ) \ channel $chan_1_ \ topoInstance $topo \ agentTrace ON \ r o ut er T r ace ON \ macTrace OFF # # C r e a t e t h e s p e c i f i e d number o f nodes [ $ v a l ( nn ) ] and " a t t a c h " them to the c h a n n el .

f o r { s e t i 0} { $ i <= $ v a l ( nn ) } { i n c r i } { s e t node_ ( $ i ) [ $ns_ node ] $node_ ( $ i ) randommotion 0 ; # d i s a b l e random motion }

# # D e f i n e node movement model # puts " Loading co nnect i o n p a t t e r n . . . " s o ur ce $ v a l ( cp ) # # D e f i n e t r a f f i c model # puts " Loading s c e n a r i o f i l e . . . " s o ur ce $ v a l ( s c ) # D e f i n e node i n i t i a l p o s i t i o n i n nam f o r { s e t i 0} { $ i <= $ v a l ( nn ) } { i n c r i } { # 4 d e f i n e s t h e node s i z e i n nam, must a d j u s t i t a c c o r d i n g t o your s c e n a r i o # The f u n c t i o n must be c a l l e d a f t e r m o b i l i t y model i s d e f i n e d $ns_ i n i t i a l _ n o d e _ p o s $node_ ( $ i ) 4 }

118

A.2. Tcl

# T e l l nodes when t h e s i m u l a t i o n ends # f o r { s e t i 0} { $ i <= $ v a l ( nn ) } { i n c r i } { $ns_ at $ v a l ( s t o p ) . 0 " $node_ ( $ i ) r e s e t " ; }

# # d e f i n e what happens a t t h e end # proc stop { } { g l o b a l ns_ t r a c e f d $ns_ f l u s h t r a c e close $tracefd } $ns_ at $ v a l ( s t o p ) .0002 " puts \ " NS E X I T I N G . . . \ " ; $ns_ h a l t "

puts $ t r a c e f d "M 0 . 0 nn $ v a l ( nn ) x $ v a l ( x ) y $ v a l ( y ) rp $ v a l ( adhocRouting ) " puts $ t r a c e f d "M 0 . 0 s c $ v a l ( s c ) cp $ v a l ( cp ) seed $ v a l ( seed ) " puts $ t r a c e f d "M 0 . 0 prop $ v a l ( prop ) ant $ v a l ( ant ) " puts " S t a r t i n g S i m u l a t i o n . . . " $ns_ run

Listing A.6: aomdv.tcl

119

A.3. Perl

A.3. Perl
A.3.1. topology_generator.pl
#! / usr / bin / p e r l # # SCEN_GENERATOR . PL F I L E TO BUILD NODE NETWORK # # P r o j e c t : S e m e s t e r T h e s i s S S 06: # E v a l u a t i o n o f s c h e d u l i n g methods o v e r # m u l t i p a t h r o u t i n g i n w i r e l e s s m o b i l e Ad Hoc n e t w o r k s # # A u t h o r s : R e gu l a Goenner , Dominik Schatzmann # # [ Perl Script ] # # Date : J u l y 2006 # # Input : # nn [ num_of_nodes ] # pause [ pausetime ] # s p e e d [ maxspeed ] # simtime [ simtime ] # x [ maxx ] # y [ maxy ] # t y p e [ t y p e o f s c e n ] # s e e d [ random s e e d ] # > [ o u t d i r / movement f i l e ] # # Output : # P r i n t s t h e c o o r d i n a t e s o f t h e nodes e i t h e r on s t d o u t o r i n t h e s p e c i f i e d f i l e . # # Types : # 00: use s e t d e s t o f NS # 1 0 : homogeneous hexagon # 2 0 : hexagon , nodes p l a c e d with j i t t e r # 3 0 : hexagon with j i t t e r , some nodes p l a c e d randomly , t o t a l 80 nodes # 4 0 : hexagon with h o t s p o t # 5 0 : c i r c u l a r random # # combined with c e r t a i n t y p e s , i n p u t v a r i a b l e s as x , y and nn may be i g n o r e d ! # # behave l i k e a r e a s o n a b l e programming language use s t r i c t ; use Switch ; # ve r s i o n of t h i s s c r i p t : my $ v e r s i o n # temp f o l d e r my $ f o l d er _ t em p mkdir $ f o l d er _ t em p ;

= " 01 " ;

= " temp " ;

# CMU p a t t e r n g e n e r a t e r : s e t d e s t my $ s e t d e s t= " . . / ns2 / ns 2.26/ indepu t i l s /cmuscengen / s e t d e s t / s e t d e s t " ; # s e e d f o r random number g e n e r a t o r my $random_seed = 0; # type of s c e n a r i o my $ s cen_ t y p e # simulation duration my $ s i m u l a t i o n _ t i m e _ s t a r t my $ s i m ul at i o n_ t i m e_ end

=();

= 0; = 0;

120

A.3. Perl

# s i m u l a t i o n dimension my $ s i m u l a t i o n _ x _ s t a r t my $ s i m ul at i o n_ x _ end my $ s i m u l a t i o n _ y _ s t a r t my $ s i m ul at i o n_ y _ end # number o f nodes my $node_number # movement my $movement_pause_time my $movement_speed

= = = =

0; 0; 0; 0;

= 0;

= 0 ; # time btw t o movements = 0 ; # mean s p e e d o f t h e node

my $DEBUG my $DISTANCE my $NODES_FIRST_LINE my $ J I T T E R ################### # MAIN # ################### # ge t arguments argument_parsing ( ) ;

= 1; = 175; = 5; = 0;

# s e t s e e d o f random number g e n e r a t o r srand ( $random_seed ) ; # select scenario if ( $ s cen_ t y p e eq " 00 " ) { # use s e t d e s t o f NS generate_scen_ typ e_0 0 ( ) ; } elsif ( $ s cen_ t y p e eq " 10 " ) { $DISTANCE = $NODES_FIRST_LINE = $JITTER = g ener at e_ s cen_ t y p e _ 1 0 ( ) ; } elsif ( $ s cen_ t y p e eq " 20 " ) { $DISTANCE = $NODES_FIRST_LINE = $JITTER = g ener at e_ s cen_ t y p e_ 2 0 ( ) ; } elsif ( $ s cen_ t y p e eq " 30 " ) { $DISTANCE = $NODES_FIRST_LINE = $JITTER = g ener at e_ s cen_ t y p e_ 3 0 ( ) ; } elsif ( $ s cen_ t y p e eq " 40 " ) { $DISTANCE = $NODES_FIRST_LINE = $JITTER = g ener at e_ s cen_ t y p e_ 4 0 ( ) } elsif ( $ s cen_ t y p e eq " 50 " ) {

175; 5; 0;

175; 5; 0;

175; 5; 0;

175; 5; 0;

121

A.3. Perl

$DISTANCE = 175; $NODES_FIRST_LINE = 5; $JITTER = 0; g ener at e_ s cen_ t y p e_ 5 0 ( ) } elsif ( $ s cen_ t y p e eq " XX " ) { $DISTANCE = 175; $NODES_FIRST_LINE = 5; $JITTER = 0; g ener at e_ s cen_ t y p e_ XX ( ) } else {

d i e ( " scen t y p e $ s cen_ t y p e not implemented \ n " ) ; } #################### sub generate_scen_ type_ 00 { # c a l l s e t d e s t o f ns / ns 2.26/ indepu t i l s /cmuscengen / # output t o s t d o u t my $command= " $ s e t d e s t " . "n $node_number " . "p $movement_pause_time " . "s $movement_speed " . "t $ s i m ul at i o n_ t i m e_ end " . "x $ s i m ul at i o n_ x _ end " . "y $ s i m ul at i o n_ y _ end " ;

p r i n t $command ; } sub g ener at e_ s cen_ t y p e_ 1 0 { # g e n e r a t e homogeneous # __ # / \ # \ __ / #

my my my my

@node_pos = ( ) ; $ d i s t _ n o d e s = $DISTANCE ; $ n n _ f i r s t _ l i n e = $NODES_FIRST_LINE ; $n_nodes_mesh = 0 ;

# c r e a t e hexagon ( $n_nodes_mesh , @node_pos ) = create_hexagon ( $ n n _ f i r s t _ l i n e , $ d i s t _ n o d e s ) ; # output output_ns ( @node_pos ) ; i f ( $DEBUG == 1 ) { output_img ( @node_pos ) ; } } sub g ener at e_ s cen_ t y p e_ 2 0 { # g e n e r a t e homogeneous with j i t t e r # _______

122

A.3. Perl

# # # # # # my my my my

/ / \ <.>

\ \ /

\ _______ /

@node_pos = ( ) ; $ d i s t _ n o d e s = $DISTANCE ; $ n n _ f i r s t _ l i n e = $NODES_FIRST_LINE ; $n_nodes_mesh = 0 ;

my $beta = $ J I T T E R ; # p l a c e nodes ( $n_nodes_mesh , @node_pos ) = create_hexagon ( $ n n _ f i r s t _ l i n e , $ d i s t _ n o d e s ) ; # add j i t t e r f o r (my $a = 0 ; $a < $n_nodes_mesh ; $a ++) { $node_pos [ $a ] [ 0 ] = $node_pos [ $a ] [ 0 ] + ( $beta $ d i s t _ n o d e s ( rand ( 2 ) 1 ) ) + $dist_nodes ; $node_pos [ $a ] [ 1 ] = $node_pos [ $a ] [ 1 ] + ( $beta $ d i s t _ n o d e s ( rand ( 2 ) 1 ) ) + $dist_nodes ; } # output output_ns ( @node_pos ) ; i f ( $DEBUG == 1 ) { output_img ( @node_pos ) ; } } sub g ener at e_ s cen_ t y p e_ 3 0 { # g e n e r a t e homogeneous with j i t t e r and l i n e a r # _______ # / . \ # / <.> \ # \ : . / # \ _______ / # my @node_pos = ( ) ; my my my my my @node_mesh $dist_nodes $nn_first_line $n_nodes_mesh $beta = (); = $DISTANCE ; = $NODES_FIRST_LINE ; = 0; = $JITTER ;

...

my @node_pos_random = ( ) ; my $ r a d i u s = $DISTANCE ( $NODES_FIRST_LINE 1 ) ; my $nn = 19; my $x = ( $ d i s t _ n o d e s ( $ n n _ f i r s t _ l i n e 1 ) ) + $ d i s t _ n o d e s ; my $y = ( $ d i s t _ n o d e s ( $ n n _ f i r s t _ l i n e 1 ) ) ( 3 ( 0 . 5 ) ) / 2 + $ d i s t _ n o d e s ; # c r e a t e hexagon ( $n_nodes_mesh , @node_mesh ) = create_hexagon ( $ n n _ f i r s t _ l i n e , $ d i s t _ n o d e s ) ; # add j i t t e r f o r (my $a = 0 ; $a < $n_nodes_mesh ; $a ++) { $node_mesh [ $a ] [ 0 ] = $node_mesh [ $a ] [ 0 ] + ( $beta $ d i s t _ n o d e s ( rand ( 2 ) 1 ) )

123

A.3. Perl

+ $dist_nodes ; $node_mesh [ $a ] [ 1 ] = $node_mesh [ $a ] [ 1 ] + ( $beta $ d i s t _ n o d e s ( rand ( 2 ) 1 ) ) + $dist_nodes ; } # p l a c e a d d i t i o n a l nodes w i t h i n a c i r c l e @node_pos_random = p l a c e _ n o d e s _ u n i f o r m _ r a n d _ c i r c l e ( $x , $y , $ r a d i u s , $nn ) ; # add t h e hexagon and t h e randomly p l a c e d nodes @node_pos = ( @node_mesh , @node_pos_random ) ; # output output_ns ( @node_pos ) ; i f ( $DEBUG == 1 ) { output_img ( @node_pos ) ; } } sub g ener at e_ s cen_ t y p e_ 4 0 { # HOTSPOT # _______ # / \ # / <... > \ # \ / # \ _______ / # #

# home j i t t e r my @node_pos my @node_mesh my $ d i s t _ n o d e s my $ n n _ f i r s t _ l i n e my $n_nodes_mesh my $beta # hotspot my @node_pos_random my $ r a d i u s my $ s h i f t my $nn

= = = = = =

(); (); $DISTANCE ; $NODES_FIRST_LINE ; 0; $JITTER ;

= = = =

(); $DISTANCE ; $DISTANCE ; 19;

my $x = ( $ d i s t _ n o d e s ( $ n n _ f i r s t _ l i n e 1 ) ) + $ s h i f t + $ d i s t _ n o d e s ; my $y = ( $ d i s t _ n o d e s ( $ n n _ f i r s t _ l i n e 1 ) ) ( 3 ( 0 . 5 ) ) / 2 + $ s h i f t + $dist_nodes ; # c r e a t e hexagon ( $n_nodes_mesh , @node_mesh ) = create_hexagon ( $ n n _ f i r s t _ l i n e , $ d i s t _ n o d e s ) ; # add j i t t e r f o r ( my $a = 0 ; $a < $n_nodes_mesh ; $a ++) { $node_mesh [ $a ] [ 0 ] = $node_mesh [ $a ] [ 0 ] + ( $beta $ d i s t _ n o d e s ( rand ( 2 ) 1 ) ) + $dist_nodes ; $node_mesh [ $a ] [ 1 ] = $node_mesh [ $a ] [ 1 ] + ( $beta $ d i s t _ n o d e s ( rand ( 2 ) 1 ) ) + $dist_nodes ; } # p l a c e a d d i t i o n a l nodes w i t h i n a c i r c l e @node_pos_random = p l a c e _ n o d e s _ u n i f o r m _ r a n d _ c i r c l e ( $x , $y , $ r a d i u s , $nn ) ; # add hexagon and random nodes @node_pos = ( @node_mesh , @node_pos_random ) ;

124

A.3. Perl

# output output_ns ( @node_pos ) ; i f ( $DEBUG == 1 ) { output_img ( @node_pos ) ; } } sub g ener at e_ s cen_ t y p e_ 5 0 { # c i r c l e 500 m # 80 node # home j i t t e r my @node_pos my $ r a d i u s my $x my $y my $node_number

= = = = =

(); ( $NODES_FIRST_LINE 1 ) $DISTANCE ; $ r a d i u s + $DISTANCE ; $ r a d i u s + $DISTANCE ; 80;

# p l a c e nodes u n i f o r m l y i n a c i r c l e @node_pos = p l a c e _ n o d e s _ u n i f o r m _ r a n d _ c i r c l e ( $x , $y , $ r a d i u s , $node_number ) ; # output output_ns ( @node_pos ) ; i f ( $DEBUG == 1 ) { output_img ( @node_pos ) ; } } sub g ener at e_ s cen_ t y p e_ XX { # DEBUG my @node_pos my my my my my = ();

@node_mesh = (); $dist_nodes = 1 2 5 ; $ n n _ f i r s t _ l i n e= 5 ; $n_nodes_mesh = 0; $beta = 0.0;

my @node_pos_random = ( ) ; my $ r a d i u s = 800; my $nn = 0; my $x = ( $ d i s t _ n o d e s ( $ n n _ f i r s t _ l i n e 1 ) ) + $ d i s t _ n o d e s ; my $y = ( $ d i s t _ n o d e s ( $ n n _ f i r s t _ l i n e 1 ) ) ( 3 ( 0 . 5 ) ) / 2 + $ d i s t _ n o d e s ; # make s c e n homogen ( $n_nodes_mesh , @node_mesh ) = create_hexagon ( $ n n _ f i r s t _ l i n e , $ d i s t _ n o d e s ) ; # jitter f o r (my $a = 0 ; $a < $n_nodes_mesh ; $a ++) { $node_mesh [ $a ] [ 0 ] = $node_mesh [ $a ] [ 0 ] + ( $beta $ d i s t _ n o d e s ( rand ( 2 ) 1 ) ) + $dist_nodes ; $node_mesh [ $a ] [ 1 ] = $node_mesh [ $a ] [ 1 ] + ( $beta $ d i s t _ n o d e s ( rand ( 2 ) 1 ) ) + $dist_nodes ; } # make random @node_pos_random = p l a c e _ n o d e s _ u n i f o r m _ r a n d _ c i r c l e ( $x , $y , $ r a d i u s , $nn ) ;

125

A.3. Perl

@node_pos = ( @node_mesh , @node_pos_random ) ; # output output_ns ( @node_pos ) ; i f ( $DEBUG == 1 ) { output_img ( @node_pos ) ; } } sub p l ace_ no d es _ uni f o r m _ r and _ s q uar e { # @ l i s t s e t _ n o d e _ l i n _ r a n d ( xs t a r t , xend , ys t a r t , yend , nnodes ) # g e n e r a t e s a l i s t with nodes t h a t a r e uniform d i s t r i b u t e d o v e r a g i v e n a r e a my my my my my $x_start $x_end $y_start $y_end $n_nodes = = = = = $_ [ 0 ] ; $_ [ 1 ] ; $_ [ 2 ] ; $_ [ 3 ] ; $_ [ 4 ] ;

my @pos my $ co o r _ x my $ co o r _ y

= (); = 0; = 0;

f o r ( my $a = 0 ; $a < $n_nodes ; $a ++) { # p o s i t i o n o f node $a $ co o r _ x = ( $x_end $ x _ s t a r t ) rand ( 1 ) + $ x _ s t a r t ; $ co o r _ y = ( $y_end $ y _ s t a r t ) rand ( 1 ) + $ y _ s t a r t ; # round $ co o r _ x = round_ns ( $ co o r _ x ) ; $ co o r _ y = round_ns ( $ co o r _ y ) ; # save c o o r d i n a t e s i n the array $pos [ $a ] [ 0 ] = $ co o r _ x ; $pos [ $a ] [ 1 ] = $ co o r _ y ; } i f ( $DEBUG == 1 ) { print "# s e t _ n o d e _ l i n _ d i s t : \ n " ; print "# x s t a r t : $ x _ s t a r t \ n " ; print "# x end : $x_end \ n " ; print "# y s t a r t : $ y _ s t a r t \ n " ; print "# y end : $y_end \ n " ; print "# nodes : $n_nodes \ n " ; } r e t u r n ( @pos ) } sub p l a c e _ n o d e s _ x x x _ r a n d _ c i r c { my $x = $_ [ 0 ] ; my $y = $_ [ 1 ] ; my $ r a d i u s = $_ [ 2 ] ; my $n_nodes = $_ [ 3 ] ; my $ ang l e my $rand my $ co o r _ x my $ co o r _ y = 0; = 0; = 0; = 0;

126

A.3. Perl

my @pos

= ();

f o r (my $a = 0 ; $a < $n_nodes ; $a ++) { # pos $ ang l e = rand ( 3 6 0 ) ; $rand = rand ( $ r a d i u s ) ; $ co o r _ x = $x + $rand s i n ( $ ang l e ) ; $ co o r _ y = $y + $rand cos ( $ ang l e ) ; # round $ co o r _ x = round_ns ( $ co o r _ x ) ; $ co o r _ y = round_ns ( $ co o r _ y ) ; # save c o o r d i n a t e s i n the array $pos [ $a ] [ 0 ] = $ co o r _ x ; $pos [ $a ] [ 1 ] = $ co o r _ y ; } r e t u r n ( @pos ) } sub p l a c e _ n o d e s _ u n i f o r m _ r a n d _ c i r c l e { # p l a c e nodes randomly and u n i f o r m l y d i s t r i b u t e d w i t h i n a c i r c l e my $x = $_ [ 0 ] ; my $y = $_ [ 1 ] ; my $ r a d i u s = $_ [ 2 ] ; my $n_nodes = $_ [ 3 ] ; my $ co o r _ x my $ co o r _ y = 0; = 0;

my $phase_one = 0 ; my $phase_sec = 0 ; my @pos = ( ) ; f o r (my $a = 0 ; $a < $n_nodes ; $a ++) { i f ( rand ( 1 ) >= 0 . 5 ) { $phase_one = 1 ; } else { $phase_one = 1; } i f ( rand ( 1 ) >= 0 . 5 ) { $phase_sec = 1 ; } else { $phase_sec = 1; } $ co o r _ x = rand ( $ r a d i u s ) ; $ co o r _ y = rand ( ( $ r a d i u s 2 $ co o r _ x 2 ) 0 . 5 ) ; $ co o r _ x = $x + $phase_one $ co o r _ x ; $ co o r _ y = $y + $phase_sec $ co o r _ y ; # round $ co o r _ x = round_ns ( $ co o r _ x ) ; $ co o r _ y = round_ns ( $ co o r _ y ) ;

127

A.3. Perl

# save c o o r d i n a t e s i n the array $pos [ $a ] [ 0 ] = $ co o r _ x ; $pos [ $a ] [ 1 ] = $ co o r _ y ; } r e t u r n ( @pos ) } sub p l a c e _ n o d e s _ t r i a n g l e { my $ l i n e = $_ [ 0 ] ; my @pos = (); # save c o o r d i n a t e s i n the array $pos [ 0 ] [ 0 ] = 0 ; $pos [ 0 ] [ 1 ] = 0 ; $pos [ 1 ] [ 0 ] = $ l i n e ; $pos [ 1 ] [ 1 ] = 0 ; $pos [ 2 ] [ 0 ] = $ l i n e / 2 ; $pos [ 2 ] [ 1 ] = $ l i n e ( 3 ( 0 . 5 ) ) / 2 ; r e t u r n ( @pos ) } sub create_hexagon { # ( $ n o d e _ i n d e x @pos ) c r e a t e _ h e x a go n ( n n _ f i r s t _ l i n e , dis_bw_node ) # g e n e r a t e s a l i s t with nodes t h a t a r e p a r t o f a mesh # c r e a t e s a hexagon with $ d i s t d i s t a n c e between t h e nodes my $ n n _ f i r s t _ l i n e my $ d i s t = $_ [ 0 ] ; = $_ [ 1 ] ; # number o f nodes on t h e f i r s t l i n e # d i s t a n c e btw two nodes

my $ y _ d e l t a _ o f f s e t = $ d i s t ( 3 ( 0 . 5 ) ) / 2 ; # d i s t a n c e btw two l i n e s o f nodes # d i s t /2 s q r t ( 3 ) , height of the e q u i l a t e r a l t r i a n g l e my $ x _ o f f s e t my $ x _ d e l t a _ o f f s e t my $node_index my @pos = ( ) ; my $ co o r _ x my $ co o r _ y = ( $nn_first_line 1 ) $dist / 2; = $dist / 2; = 0;

= 0; = 0;

# upper p a r t o f hexagon my $a = 0 ; my $b = 0 ; f o r ( $a = 0 ; $a < $ n n _ f i r s t _ l i n e ; $a ++) # l i n e s { f o r ( $b = 0 ; $b < $ n n _ f i r s t _ l i n e + $a ; $b ++) { # p o s i t i o n o f node $ n o d e _ i n d e x $ co o r _ x = ( $ x _ o f f s e t $a $ x _ d e l t a _ o f f s e t ) + $b $ d i s t ; $ co o r _ y = $ y _ d e l t a _ o f f s e t $a ; # round $ co o r _ x = round_ns ( $ co o r _ x ) ; $ co o r _ y = round_ns ( $ co o r _ y ) ; # save c o o r d i n a t e s i n the array $pos [ $node_index ] [ 0 ] = $ co o r _ x ; $pos [ $node_index ] [ 1 ] = $ co o r _ y ; # n e x t node $node_index + + ;

128

A.3. Perl

} } # l o w e r p a r t o f hexagon f o r ( $a = 1 ; $a < $ n n _ f i r s t _ l i n e ; $a ++) # l i n e s { f o r ( $b = 0 ; $b < ( 2 $ n n _ f i r s t _ l i n e 1 ) $a ; $b ++) { # p o s i t i o n o f node $ n o d e _ i n d e x $ co o r _ x = ( $a $ x _ d e l t a _ o f f s e t ) + $b $ d i s t ; $ co o r _ y = ( $ y _ d e l t a _ o f f s e t ( $ n n _ f i r s t _ l i n e 1 ) ) + $ y _ d e l t a _ o f f s e t $a ; # round $ co o r _ x = round_ns ( $ co o r _ x ) ; $ co o r _ y = round_ns ( $ co o r _ y ) ; # save c o o r d i n a t e s i n the array $pos [ $node_index ] [ 0 ] = $ co o r _ x ; $pos [ $node_index ] [ 1 ] = $ co o r _ y ; # n e x t node $node_index + + ; } } r e t u r n ( $node_index , @pos ) } sub o ut p ut _ s cr een { # o u t p u t _ s c r e e n ( \ @node_pos ) my @pos = @_ ; p r i n t "# node placement : \ n " ; f o r (my $a = 0 ; $a < s c a l a r ( @pos ) ; $a ++) { p r i n t "# node : \ t $ a \ t x : \ t $ p o s [ $a ] [ 0 ] \ t } return } sub output_ns { # o u t p u t _ n s ( @node_pos ) my @pos = @_ ; p r i n t "# s cen_ g ener a t o r V e r s i o n : $ v e r s i o n \ n " ; p r i n t "# f i l e generated at : " , l o c a l t i m e ( time ) , " \ n " ; p r i n t " #\ t xco o r \ t yco o r \ t zco o r \ n " ; f o r (my $a = 0 ; $a < s c a l a r ( @pos ) ; $a ++) { p r i n t ( " \ $node_ ( $a ) s e t X_ $pos [ $a ] [ 0 ] ; \ n " ) ; p r i n t ( " \ $node_ ( $a ) s e t Y_ $pos [ $a ] [ 1 ] ; \ n " ) ; p r i n t ( " \ $node_ ( $a ) s e t Z_ " , round_ns ( 0 ) , " ; \ n " ) ; } return } sub output_img { # out_imag ( \ @node_pos ) my @pos = @_ ; # w r i t e data f i l e

y : \ t $ p o s [ $a ] [ 1 ] \ n " ;

129

A.3. Perl

# p r i n t " g e n e r a t e gnu data f i l e . . . \ n " ; open ( GNUPLOT_DATA , " > $ f o l d er _ t em p / g nup l o t _ d at a . tmp " ) | | d i e " can t w r i t e g nup l o t _ d at a . tmp f i l e " ; p r i n t GNUPLOT_DATA " #\ t xco o r \ t \ t yco o r \ t \ t Z =1 \ n " ;

f o r ( my $a = 0 ; $a < s c a l a r ( @pos ) ; $a ++) { p r i n t GNUPLOT_DATA " $pos [ $a ] [ 0 ] \ t \ t $pos [ $a ] [ 1 ] \ t \ t } c l o s e ( GNUPLOT_DATA ) ; #w r i t e header f i l e # p r i n t " g e n e r a t e gnu p l o t . . . \ n " ; open ( GNUPLOT_HEADER , " > $ f o l d er _ t em p / gnuplot_header . tmp " ) | | d i e " can t w r i t e gnuplot_header . tmp f i l e " ;

1\n" ;

p r i n t GNUPLOT_HEADER " s e t xrange [ 0 : 1 7 0 0 ] s e t yrange [ 0 : 1 7 0 0 ] s e t view map s e t s i z e square set p o i nt s i z e 2 s e t t i t l e \ " s c e n a r i o g ener at o r \ " #s e t n o x t i c #s e t n o y t i c s e t nokey s e t output \ " $ f o l d er _ t em p / nodes . eps \ " s e t term p o s t s c r i p t eps enhanced c o l o r s p l o t \ " $ f o l d er _ t em p / g nup l o t _ d at a . tmp \ " us i ng 1 : 2 : 3 with p o i n t s 7 7 " ; c l o s e ( GNUPLOT_HEADER ) ; # make g r a p h i c p r i n t gnuplot $ f o l d er _ t em p / gnuplot_head er . tmp ; # view p l o t p r i n t gv $ f o l d er _ t em p / nodes . eps ; } sub round_ns { #round a number t o 1 2 d i g i t s a f t e r z e r o my $ i n = $_ [ 0 ] ; my $out = s p r i n t f ( " % . 1 2 f " , $ i n ) ; r e t u r n ( $out ) } sub argument_parsing { # c h e c k number o f arguments and v a l i d a t e t h e i n p u t i f ( s c a l a r ( @ARGV) ! = 1 6 ) { die " use : nn [ num_of_nodes ] " . "pause [ pausetime ] " . "speed [ maxspeed ] " . "simtime [ simtime ] " . "x [ maxx ] " . "y [ maxy ] " . "t y p e [ t y p e o f scen ] " . "seed [ random seed ] > " . " [ o u t d i r /movementf i l e ] \ n " ; } f o r ( my $a = 0 ; $a < s c a l a r (@ARGV ) ; $a = $a + 2 ) {

130

A.3. Perl

i f ( $ARGV [ $a ] eq "nn " ) { i f ( $ARGV [ $a + 1 ] > 0) { $node_number = $ARGV [ $a + 1 ] ; } else { d i e " number o f node $ARGV [ $a + 1 ] ? ! ? \ n " ; } } e l s i f ( $ARGV [ $a ] eq "seed " ) { $random_seed = $ARGV [ $a + 1 ] ; } e l s i f ( $ARGV [ $a ] eq "pause " ) { i f ( $ARGV [ $a + 1 ] >= 0) { $movement_pause_time = $ARGV [ $a + 1 ] ; } else { d i e " pause time $ARGV [ $a + 1 ] ? ! ? \ n " ; } } e l s i f ( $ARGV [ $a ] eq "speed " ) { i f ( $ARGV [ $a + 1 ] >= 0) { $movement_speed = $ARGV [ $a + 1 ] ; } else { d i e " speed $ARGV [ $a + 1 ] ? ! ? \ n " ; } } e l s i f ( $ARGV [ $a ] eq "simtime " ) { i f ( $ARGV [ $a + 1 ] > 0) { $ s i m ul at i o n_ t i m e_ end = $ARGV [ $a + 1 ] ; } else { d i e " time $ARGV [ $a + 1 ] ? ! ? \ n " ; } } e l s i f ( $ARGV [ $a ] eq "x " ) { i f ( $ARGV [ $a + 1 ] > 0) { $ s i m ul at i o n_ x _ end = $ARGV [ $a + 1 ] ; } else { d i e " x $ARGV [ $a + 1 ] ? ! ? \ n " ; } } e l s i f ( $ARGV [ $a ] eq "y " ) { i f ( $ARGV [ $a + 1 ] > 0) { $ s i m ul at i o n_ y _ end = $ARGV [ $a + 1 ] ; } else { d i e " y $ARGV [ $a + 1 ] ? ! ? \ n " ;

131

A.3. Perl

} } e l s i f ( $ARGV [ $a ] eq "t y p e " ) { $ s cen_ t y p e = $ARGV [ $a + 1 ] ; } e l s i f ( $ARGV [ $a ] eq "seed " ) { i f ( $ARGV [ $a + 1 ] >= 0) { $random_seed = $ARGV [ $a + 1 ] ; } else { d i e " seed $ARGV [ $a + 1 ] ? ! ? \ n " ; } }

else { p r i n t " unknown argument $ARGV [ $a ] " ; } } i f ( $DEBUG { print print print print print print print print print } } sub double_check { my @pos_old = @_ ; my @pos_new = ( ) ; my $ f l a g = 0 ; # not y e t implemented == 1 ) "# DEBUG : argument_parsing ( ) \ n " ; "# number o f nodes : $node_number \ n " ; "# random seed : $random_seed \ n " ; "# x end $ s i m ul at i o n_ x _ end \ n " ; "# y end $ s i m ul at i o n_ y _ end \ n " ; "# scen t y p e : $ s cen_ t y p e \ n " ; "# s i m u l a t i o n time : $ s i m ul at i o n_ t i m e_ end \ n " ; "# movement pause time : $movement_pause_time\ n " ; "# movement speed : $movement_speed \ n " ;

r e t u r n @pos_new }

Listing A.7: topology_generator.pl

132

A.3. Perl

A.3.2. traffic_generator.pl
#! / usr / bin / p e r l # # TRAFFIC_GENERATOR . PL F I L E TO GENERATE DIFFERENT T R A F F I C LOADS # # P r o j e c t : S e m e s t e r T h e s i s S S 06: # E v a l u a t i o n o f s c h e d u l i n g methods o v e r # m u l t i p a t h r o u t i n g i n w i r e l e s s m o b i l e Ad Hoc n e t w o r k s # # A u t h o r s : R e gu l a Goenner , Dominik Schatzmann # # [ Perl Script ] # # Date : J u l y 2006 # # Input : # t y p e [ c b r | t c p ] # nn [ number o f nodes ] # s e e d [ random s e e d ] # nc [ number o f c o n n e c t i o n s ] # r a t e [ p a c k e t / s ] # p k t s i z e [ p a c k e t s i z e ] # # Output : # P r i n t s t h e output t o t h e s t d o u t , c r e a t e s i n f o r m a t i o n s about # c o n n e c t i o n s and t h e i r p a c k e t r a t e and t h i s can be used as # t r a f f i c model i n t h e t c l s c r i p t f o r NS . # # # Behave l i k e a r e a s o n a b l e programming language use s t r i c t ; # ======================================================================================= # Default S c r i p t Options # ======================================================================================= my $ v e r s i o n my $node_number my $random_seed my my my my = 01 ; = 0; = 0; # ve r s i o n of t h i s s c r i p t # number o f nodes # random s e e d # # # # # # number o f c o n n e c t i o n s packet s i z e in byte number o f p a c k e t s p e r s e c o n d i n ve r s e of packet rate time between two p a c k e t type of t r a f f i c ( tcp or cbr )

$connection_number = 0; $connection_packet_size = 0; $connection_packet_rate = 0; $co nnect io n_packet _int er val = 0;

my $ c o n n e c t i o n _ t r a f f i c _ t y p e = 0 ; my $ s i m u l a t i o n _ s t a r t _ t i m e #my $ s i m u l a t i o n _ e n d _ t i m e my $warm_up_end_time my $warm_up_start_time my $max_source_per_node my $max_sink_per_node my $DEBUG = 0 ; = 0; = 1000; = 180; = 0; = 1; = 1;

# not used y e t

# l i m i t e d number o f c o n n e c t i o n s p e r node

# ======================================================================================= # # MAIN # # ======================================================================================= # ge t arguments o f t r a f f i c _ g e n e r a t o r . p l

133

A.3. Perl

argument_parsing ( ) ; # p r i n t header print "# T r a f f i c G ener at o r V e r s i o n : $ v e r s i o n \ n\ n " ; print "# nodes : $node_number , conn : $connection_number , " . " send r a t e : $ c o n n e c t i o n _ p a c k e t _ r a t e , " . " seed : $random_seed \ n#" ; # s e t random s e e d srand ( $random_seed ) ; my $ c b r _ s o u r c e _ i n d e x = 0 ; # Unique number t o i d e n t i f y CBR s o u r c e

# c h e c k i f problem has a s o l u t i o n : # max . c o n n e c t i o n < ( max s o u r c e p e r node ) ( number node ) i f ( $connection_number > ( $node_number $max_source_per_node ) | | $connection_number > ( $node_number $max_sink_per_node ) ) { p r i n t " can t s o l v e t h i s problem . . . more co nnect i o ns than allowed . . . " ; die ; } my my my my $ s r c_ no d e = 0; $dst_node = 0; @n_source_per_node =(); @n_sink_per_node = ( ) ;

# g e n e r a t e f o r each c o n n e c t i o n a s r c and d s t # f o r (my $ a =0; $a < $connection_number ; $a ++) { # s e l e c t random s o u r c e and d e s t i n a t i o n # #Node number between (1 $node_number ) $dst_node = i n t ( rand ( $node_number ) ) ; $ s r c_ no d e = i n t ( rand ( $node_number ) ) ; #c h e c k # number o f e s t a b l i s h e d c o n n e c t i o n o f t h e nodes # s o u r c e != d e s t i n a t i o n # node_number < $node_number ( c h e c k boundary ) w hi l e ( ( $n_source_per_node [ $ s r c_ no d e ] >= $max_source_per_node ) | | ( $ n_ s i nk_ p er _ no d e [ $dst_node ] >= $max_source_per_node ) | $dst_node == $ s r c_ no d e | | $dst_node == $node_number | | $ s r c_ no d e == $node_number ) { i f ( $DEBUG == 1 ) { p r i n t " s r c : $ s r c_ no d e \ n " ; p r i n t " d s t : $dst_node \ n " ; p r i n t " number o f s o u r c e s o f node $ s r c_ no d e : " , $n_source_per_nod e [ $ s r c_ no d e ] , " ( CHECK : " , $n_source_per_node [ $ s r c_ no d e ] >= $max_source_per_node , " ) \ n " ; p r i n t " number o f s i n k s o f node $dst_node : " , $ n_ s i nk_ p er _ no d e [ $dst_node ] , " ( CHECK : " , $ n_ s i nk_ p er _ no d e [ $dst_node ] >= $max_sink_per_node , " ) \ n " ; } $dst_node = i n t ( rand ( $node_number ) ) ; $ s r c_ no d e = i n t ( rand ( $node_number ) ) ; } #add new c o n n e c t i o n $n_source_per_node [ $ s r c_ no d e ] + + ; $ n_ s i nk_ p er _ no d e [ $dst_node ] + + ; # c r e a t e tag f o r NS

134

A.3. Perl

i f ( $ c o n n e c t i o n _ t r a f f i c _ t y p e eq " cb r " ) { c r e a t e _ c b r _ c o n n e c t i o n ( $src_node , $dst_node , $ c b r _ s o u r c e _ i n d e x ) ; $cbr_source_index ++; } e l s i f ( $ c o n n e c t i o n _ t r a f f i c _ t y p e eq " t cp " ) { d i e " t cp i s not y e t implemented \ n " ; } else { d i e " unknown \ $ c o n n e c t i o n _ t r a f f i c _ t y p e : $ c o n n e c t i o n _ t r a f f i c _ t y p e " ; } } p r i n t " #\n# $connection_number co nnect i o ns e s t a b l i s h e d \ n#" ;

# ====================================================================== sub argument_parsing { # perl traffic_generator . pl # [ t y p e c b r | t c p ] # [nn nodes ] # [ s e e d s e e d ] # [nc number o f c o n n e c t i o n s ] # [ r a t e r a t e ] # [ p k t s i z e p a c k e t s i z e ] # c h e c k number o f arguments i f ( s c a l a r (@ARGV ) ! = 1 2 ) { d i e " use : t y p e [ cb r | t cp ] " . "nn [ number o f nodes ] " . "seed [ random seed ] " . "nc [ number o f co nnect i o ns ] " . "r a t e [ p acket / s ] " . "p k t s i z e [ p acket s i z e ] \ n " ; } # input validation f o r (my $a = 0 ; $a < s c a l a r ( @ARGV ) ; $a = $a + 2 ) { i f ( $ARGV [ $a ] eq "t y p e " ) { i f ( $ARGV [ $a + 1 ] eq " t cp " | | $ARGV [ $a + 1 ] eq " cb r " ) { $ c o n n e c t i o n _ t r a f f i c _ t y p e = $ARGV [ $a + 1 ] ; } else { d i e " t y p e $ARGV [ $a + 1 ] i s not implemented \ n " ; } } e l s i f ( $ARGV [ $a ] eq "nn " ) { i f ( $ARGV [ $a + 1 ] > 0 ) { $node_number = $ARGV [ $a + 1 ] ; } else { d i e " node number $ARGV [ $a + 1 ] ? ! ? \ n " ; } } e l s i f ( $ARGV [ $a ] eq "seed " ) { $random_seed = $ARGV [ $a + 1 ] ;

135

A.3. Perl

} e l s i f ( $ARGV [ $a ] eq "nc " ) { i f ( $ARGV [ $a + 1 ] > 0 ) { $connection_number = $ARGV [ $a + 1 ] ; } else { d i e " number o f co nnect i o ns $ARGV [ $a + 1 ] ? ! ? \ n " ; } } e l s i f ( $ARGV [ $a ] eq "r a t e " ) { i f ( $ARGV [ $a + 1 ] > 0) { $ c o n n e c t i o n _ p a c k e t _ r a t e = $ARGV [ $a + 1 ] ; $connection_packet_interval = 1 / $connection_packet_rate ; } else { d i e " p acket r a t e $ARGV [ $a + 1 ] ? ! ? \ n " ; } } e l s i f ( $ARGV [ $a ] eq "p k t s i z e " ) { i f ( $ARGV [ $a + 1 ] > 0) { $ c o n n e c t i o n _ p a c k e t _ s i z e = $ARGV [ $a + 1 ] ; } else { d i e " p acket s i z e $ARGV [ $a + 1 ] ? ! ? \ n " ; } } else { p r i n t " unknown argument $ARGV [ $a ] " ; } } i f ( $DEBUG { print print print == 1 ) "# "# "# DEBUG : argument_parsing ( ) \ n " ; number o f nodes : $node_number \ n " ; random seed : $random_seed \ n " ; t r a f f i c type : $co nnect i o n _ t r a ffi c _t y pe \n" ; number o f co nnect i o ns : $connection_number \ n " ; p acket i n t e r v a l : $ c o n n e c t i o n _ p a c k e t _ i n t e r v a l \ n \ n " ;

p r i n t "# p r i n t "# p r i n t "# } }

sub c r e a t e _ c b r _ c o n n e c t i o n { # w r i t e NScode t o t h e S t o u t my $ s r c_ no d e = s h i f t ; my $dst_node = s h i f t ; my $cbr_source_number = s h i f t ; # unique number t o i d e n t i f y CBR s o u r c e my $ t r a f f i c _ s t a r t _ t i m e = ( rand ( 1 ) ( $warm_up_end_time $warm_up_start_time ) ) + $simulation_start_time ; #my $ t r a f f i c _ e n d _ t i m e = $ s i m u l a t i o n _ e n d _ t i m e ;

136

A.3. Perl

p r i n t " \ n#\n# $ s r c_ no d e co nnect i ng to $dst_node at time $ t r a f f i c _ s t a r t _ t i m e \ n#\n " ; # source p r i n t " s e t udp_ ( $cbr_source_number ) \ [ new Agent /UDP \ ] \ n " ; print print print print print " s e t cb r _ ( $cbr_source_number ) \ [ new A p p l i c a t i o n / T r a f f i c / CBR \ ] \ n " ; " \ $ cb r _ ( $cbr_source_number ) s e t p a c k e t S i z e _ $ c o n n e c t i o n _ p a c k e t _ s i z e \ n " ; " \ $ cb r _ ( $cbr_source_number ) s e t i n t e r v a l _ $ c o n n e c t i o n _ p a c k e t _ i n t e r v a l \ n " ; " \ $ cb r _ ( $cbr_source_number ) s e t random_ 1 \ n " ; " \ $ cb r _ ( $cbr_source_number ) s e t maxpkts_ 10000\n " ;

p r i n t " \ $ cb r _ ( $cbr_source_number ) at t achagent \ $udp_ ( $cbr_source_number ) \ n " ; p r i n t " \ $ns_ at t achagent \ $node_ ( $ s r c_ no d e ) \ $udp_ ( $cbr_source_number ) \ n " ; # sink p r i n t " s e t n u l l _ ( $cbr_source_number ) \ [ new Agent / N u l l \ ] \ n " ; p r i n t " \ $ns_ at t achagent \ $node_ ( $dst_node ) \ $ n u l l _ ( $cbr_source_number ) \ n " ; # c o n n e c t s o u r c e and s i n k p r i n t " \ $ns_ connect \ $udp_ ( $cbr_source_number ) \ $ n u l l _ ( $cbr_source_number ) \ n " ; # s e t event p r i n t " \ $ns_ at $ t r a f f i c _ s t a r t _ t i m e \ " \ $ cb r _ ( $cbr_source_number ) s t a r t \ " \ n " ; } # ======================================================================

Listing A.8: traffic_generator.pl

137

A.3. Perl

A.3.3. create_simulation.pl
#! / usr / bin / p e r l # # create_simulation . pl : # F I L E TO GENERATE PACKAGE FOR SIMULATION SETUP # # P r o j e c t : S e m e s t e r T h e s i s S S 06: # E v a l u a t i o n o f s c h e d u l i n g methods o v e r # m u l t i p a t h r o u t i n g i n w i r e l e s s m o b i l e Ad Hoc n e t w o r k s # # A u t h o r s : R e gu l a Goenner , Dominik Schatzmann # # [ Perl Script ] # # Date : J u l y 2006 # # Input : # [ Parameter S e t t i n g s i n t h i s f i l e ] # # Output : # # [ " d a t a p a c k e t . t a r . gz " ] # # T h i s s c r i p t s c r e a t e s a t a r . gz p a c k e t t h a t c o n t a i n s a l l needed f i l e s t o s t a r t # t h e s i m u l a t i o n on t h e condor c l u s t e r o f I T E T # # Usage : # ( 0 . I n s t a l l remote s o u r c e p a c k e t o f NS on NFS o f I T E T ) # ( 0 . Adapt p a t h s i n remote . p l ) # 1 . Change " System s e t t i n g s " # 2 . Change " S i m u l a t i o n Parameter " # 3 . exec : p e r l c r ea t e_s i m u l a t i o n . p l # # ( 4 . s t a r t condor j o b s with c o n d o r _ s u bmit r u n _ s i m u l a t i o n on I T E T machine ) # ( 5 . c h e c k queue o f condor with condor_q g l o b a l ) # ( 6 . wait u n t i l a l l j o b s a r e f i n i s h e d o r remove j o b s with condor_rm ) # ( 7 . copy back r e s u l t i n $sim_data ) # # Idea : # c r e a t e a f o l d e r under $ o u t _ d i r t o s t o r e a l l data f o r t h i s $ v e r s i o n o f t h e s i m u l a t i o n # # check i f s c e n a r i o pattern ( t r a f f i c / topology ) e x i s t s i n $ p a t t e r n _ d i r # No > c r e a t e p a t t e r n with t h e h e l p o f " t r a f f i c _ g e n e r a t o r . p l " and # " t o p o l o g y _ g e n e r a t o r . p l " and s a v e them i n t h e $ p a t t e r n _ d i r # # copy p a t t e r n t o $ o u t _ d i r # . # w r i t e condor i n s t r u c t i o n f i l e r u n _ c o n d o r # c h e c k i f data p o i n t i s a l l r e a d y s i m u l a t e d ? # > c h e c k i f . sim f i l e e x i s t a l l r e a d y i n $sim_data # YES s k i p # NO w r i t e one condor j o b # # t a r a l l data # # copy data t o i t e t # # u n t a r data # # s t a r t condor j o b with c o n d o r _ s u bmit r u n _ s i m u l a t i o n on i t e t machine # # # t r a f f i c generator : see t r a f f i c _ g e n e r a t o r . pl # # topology generator : see topology_generator . pl #

138

A.3. Perl

# condor : s e e : www. computing . ee . e t h z . ch > programming > condor # # # Behave l i k e a r e a s o n a b l e programming language use s t r i c t ; # # System s e t t i n g s # # E d i t t h i s v a r i a b l e s t o run t h e s c r i p t on your system

# Simulation s D es cri p ti o n # # r e l e a s e number my $ v e r s i o n # t e s t number XX my $ t e s t s e r i e s = " D002 " ;

= " 002 " ;

# d e s c r i p t i o n of t h i s simulation my $ d e s c r i p t i o n = " Hexagon , with h e l l o , with i n f o , no ping " ; # F o l d e r o f t h e network s i m u l a t o r # # path t o NS my $ n s _ d i r = " . . / ns2 / ns 2.26 " ; # F o l d e r of simulation r e s u l t s # # ( used t o c h e c k i f t h e p o i n t i s a l l r e a d y s i m u l a t e d ) my $sim_data = " . . / sim_data / $ v e r s i o n " ; mkdir $sim_data ; # F o l d e r of simulation pattern # my $ p a t t e r n _ d i r = " . . / pattern " ; mkdir $ p a t t e r n _ d i r ; # Output # # f o l d e r f o r OUTPUT my $ o u t _ d i r = " . . / transit " ; mkdir $ o u t _ d i r ; # f o l d e r fo r packet my $ p a c k e t _ d i r = " $ o u t _ d i r / $ v e r s i o n$ t e s t s e r i e s " ; mkdir $ p a c k e t _ d i r ; # Scripts # # this f i l e my $ c r e a t e _ f i l e = " create_simulation " ; # t r a f f i c generator my $ t r a f f i c _ g e n = " traffic_generator . pl " ; # topology generator my $topology_gen = " topology_generator . pl " ; # e x e c u t a b l e o f condor my $rem_exe = " remote . p l " ; # c a l l e d by remote . p l t o s t a r t NS

139

A.3. Perl

my $ r em _ s t ar t _ ns

= " aomdv . t c l " ;

# c a l l e d by remote . p l t o p r o c e s s output data my $rem_gawk_tr_val = " t r _ t o _ v a l . awk " ; my $rem_gawk_sim = " v a l _ t o _ s i m . awk " ;

# Us e r # my $user_name = " schadomi " ;

# i t e t username

# Remote machine # my $remote_host = " t a r d i s d02 . ee . et hz . ch " ; my $ r em o t e_ ho s t _ d i r = " /home/ schadomi / e x t r a " ;

# NFS s p a c e t o s a v e t h e s i m u l a t i o n

# # Simulation S e t t i n g s # # General my $n_of_run # Variables my @queue_type my @queue_length my @dim_x my @dim_y my @n_node my @sim_time my @sim_progress # Moving p a t t e r n my @pause_time my @max_speed my @scen_type # T r a f f i c pattern my @source_type my @num_connect my @p acket _ s i z e my @packet_rate # AOMDV parameter my @sched_type = 5; ## number o f s i m u l a t i o n s

= = = = =

( Queue / D r o p T a i l / PriQueue ) ; ## i n t e r f a c e queue t y p e (50); ## l e n g t h o f i n t e r f a c e queue ( i n p a c k e t s ) (2000); ## x ( network dim ) > 2000 f o r s c e n e != 00 (2000); ## y ( network dim ) > 2000 f o r s c e n e != 00 (80); ## number o f nodes > 80 f o r s c e n e != 00 ## s i m u l a t i o n d u r a t i o n ## s i m u l a t i o n p r o g r e s s , not used

= (1000); = (100);

= (0); = ( 0.0 ) ; = ( 40 ) ;

## pause time ( pause between moving ) ## max s p e e d [m/ s ] ## s e e t o p o l o g y _ g e n e r a t o r . p l f o r h e l p

= ( cb r ) ; = (50); = (256);

## t y p e o f t r a f f i c s o u r c e ( " c b r " o r " t c p " ) ## number o f c o n n e c t i o n s ## p a c k e t s i z e [ B y t e s ] ## p a c k e t r a t e [ p a c k e t / s e c o n d ]

= ( 1 . 0 , 1 . 5 , 2.0 ) ;

= ( 0 , 1 , 2 , 3 ) ; ## ## ## ## ## ## ## 0 = 1 = 2 = 3 = 4 = 5 = max

## t y p e o f path s c h e d u l e r S e l e c t o n l y one [ aomdv ] ( s h o r t e s t path ) Round Robin [ RR ] Weighted RR [WRR] ( 1 / hop ) S e l e c t i v e WRR [ SWRR ] WRR RTT ( needs p i n g ) Neighbour ( needs p i n g ) o f p a t h s between s o u r c e and d e s t i n a t i o n

my @max_path

= (1);

# # # global va ri a b l es # # Pattern generation my $seed = 0; # random s e e d f o r t r a f f i c g e n e r a t o r

140

A.3. Perl

my @z ei l en ; my $ f i l e_ nam e ; ## my my my my my my my my my my my my my my my my my loop v a r i a b l e s : $ n_ o f _ r un_ i d x $ q ueue_ t y p e_ i d x $ q ueue_ l eng t h_ i d x $dim_x_idx $dim_y_idx $n_node_idx $ s i m _ t i m e_ i d x $sim_progress_idx $ p aus e_ t i m e_ i d x $max_speed_idx $scen_type_idx $source_type_idx $num_connect_idx $packet_size_idx $packet_rate_idx $ s ched _ t y p e_ i d x $max_path_idx

# a r r a y t o manipulate s e e d # temp v a r i a b l e t o g e n e r a t e path names

= = = = = = = = = = = = = = = = =

0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0;

# p r i n t " \ n CREATE START SCRIPT \ n " ; # p r i n t " cr eat e f o l d e r s t r uct ur e \n " ; p r i n t rm r $ p a c k e t _ d i r ; mkdir $ p a c k e t _ d i r ; my $ p acket _ s i m mkdir $ p acket _ s i m ; my $ l o g _ d i r mkdir $ l o g _ d i r ; my $ l o g _ e r r o r mkdir $ l o g _ e r r o r ; my $ l o g _ o ut mkdir $ l o g _ o ut ; = " $ p a c k e t _ d i r / sim_data " ; # remove o l d data

# s i m u l a t i o n out

= " $ p a c k e t _ d i r / co nd o r _ l o g " ;

# f o l d e r t o s t o r e condor l o g s

= " $log_dir / error " ;

# condor e r r o r s

= " $ l o g _ d i r / out " ;

# condor s t d o u t

my $ p a c k e t _ p a t t e r n = " $ p a c k e t _ d i r / p a t t e r n " ; mkdir $ p a c k e t _ p a t t e r n ; p r i n t " copy f i l e s . . . \ n" ;

# f o l d e r of t r a n s i t packet

# copy e x e c u t a b l e o f NS cp $ n s _ d i r / ns $packet_dir ; # copy remote s c r i p t s cp $rem_exe cp $ r em _ s t ar t _ ns cp $rem_gawk_tr_val cp $rem_gawk_sim # copy m y s e l f cp $ c r e a t e _ f i l e

$packet_dir $packet_dir $packet_dir $packet_dir

; ; ; ;

$packet_dir ;

pr int " write descr ipt ion . . . \ n" ; echo $ d e s c r i p t i o n > $ p a c k e t _ d i r / d e s c r i p t i o n . t x t ; # G e n e r a t e needed P a t t e r n

141

A.3. Perl

p r i n t " \ n ############# START :

Generate P a t t e r n ################# \ n " ;

f o r ( $ n_ o f _ r un_ i d x = 0 ; $ n_ o f _ r un_ i d x < $n_of_run ; $ n_ o f _ r un_ i d x ++) #r u n s { p r i n t " \n " ; p r i n t " run number : $ n_ o f _ r un_ i d x \ n " ; p r i n t " \n " ; f o r ( $dim_x_idx = 0 ; $dim_x_idx < @dim_x ; $dim_x_idx ++) { p r i n t " \ n dimension x : \ t \ t$dim_x [ $dim_x_idx ] \ n " ; f o r ( $dim_y_idx = 0 ; $dim_y_idx < @dim_y ; $dim_y_idx ++) { p r i n t " \ n dimension y : \ t \ t$dim_y [ $dim_y_idx ] \ n " ; f o r ( $n_node_idx = 0 ; $n_node_idx < @n_node ; $n_node_idx ++) { p r i n t " \ n number o f nodes : \ t \ t$n_node [ $n_node_idx ] \ n " ; f o r ( $ s i m _ t i m e_ i d x = 0 ; $ s i m _ t i m e_ i d x < @sim_time ; $ s i m _ t i m e_ i d x ++) { p r i n t " \ n s i m u l a t i o n d u r a t i o n : \ t \ t$sim_time [ $ s i m _ t i m e_ i d x ] \ n " ;

# make f o l d e r s # p r i n t " \ n \ t make f o l d e r s . . . \ n " ; # local # g e n e r a t e p a t t e r n f o l d e r i f i t does not e x i s t mkdir " $ p a t t e r n _ d i r " ; mkdir " $ p a t t e r n _ d i r / $dim_x [ $dim_x_idx]$dim_y [ $dim_y_idx ] $sim_time [ $ s i m _ t i m e_ i d x ] " ; mkdir " $ p a t t e r n _ d i r / $dim_x [ $dim_x_idx]$dim_y [ $dim_y_idx ] $sim_time [ $ s i m _ t i m e_ i d x ] " . " / m o b i l i t y $ n_ o f _ r un_ i d x " ; mkdir " $ p a t t e r n _ d i r / $dim_x [ $dim_x_idx]$dim_y [ $dim_y_idx ] $sim_time [ $ s i m _ t i m e_ i d x ] " . " / s o ur ces$ n_ o f _ r un_ i d x " ; # packet # g e n e r a t e p a t t e r n f o l d e r i f does not e x i s t mkdir " $ p a c k e t _ p a t t e r n / $dim_x [ $dim_x_idx ]$dim_y [ $dim_y_idx ] " . "$sim_time [ $ s i m _ t i m e_ i d x ] " ; mkdir " $ p a c k e t _ p a t t e r n / $dim_x [ $dim_x_idx ]$dim_y [ $dim_y_idx ] " . "$sim_time [ $ s i m _ t i m e_ i d x ] / m o b i l i t y $ n_ o f _ r un_ i d x " ; mkdir " $ p a c k e t _ p a t t e r n / $dim_x [ $dim_x_idx ]$dim_y [ $dim_y_idx ] " . "$sim_time [ $ s i m _ t i m e_ i d x ] / s o ur ces$ n_ o f _ r un_ i d x " ;

# s e t random s e e d # p r i n t " \ t s e t random seed . . . \ n " ; $seed = $ n_ o f _ r un_ i d x + 1 ; # overflow check i f ( $seed > 3 2 7 6 7 ) { d i e ( " running out o f seeds ( b i g g e r then i n t 1 6 ) . . . \ n " ) ; } e l s i f ( $seed == 0) { d i e ( "BUG : t r a f f i c g ener at o r does not work with seed == 0\n " ) ; } #Check i f s e e d . t x t f i l e e x i s t s i f ( 1 == e " $ p a t t e r n _ d i r / $dim_x [ $dim_x_idx]$dim_y [ $dim_y_idx ] " . "$sim_time [ $ s i m _ t i m e_ i d x ] / m o b i l i t y $ n_ o f _ r un_ i d x / seed . t x t " ) { # r e a d s e e d out o f f i l e p r i n t " \ t \ t \ t read seed out o f f i l e : " ; open ( F I L E , " < $ p a t t e r n _ d i r / $dim_x [ $dim_x_idx ]$dim_y [ $dim_y_idx ] " .

142

A.3. Perl

"$sim_time [ $ s i m _ t i m e_ i d x ] / m o b i l i t y $ n_ o f _ r un_ i d x / seed . t x t " ) | | d i e " can t l o ad seed f i l e " ; @z ei l en = < F I L E > ; close ( FILE ) ; $seed = $ z e i l e n [ 0 ] ; p r i n t " $seed \ n " ; } else { # s e t s e e d and w r i t e i t i n t o t h e # " m o b i l i t yRUN/ s e e d . t x t " and " s o u r c e s RUN/ s e e d . t x t " p r i n t " \ t \ t \ t g ener at e seed and s t o r e i t i n f i l e : " ; open ( F I L E , " > $ p a t t e r n _ d i r / $dim_x [ $dim_x_idx]$dim_y [ $dim_y_idx ] " . "$sim_time [ $ s i m _ t i m e_ i d x ] / m o b i l i t y $ n_ o f _ r un_ i d x / seed . t x t " ) | | d i e " can t w r i t e seed f i l e " ; p r i n t " $seed \ n " ; p r i n t F I L E $seed ; close ( FILE ) ; #copy f i l e i n s o u r c e f o l d e r my $command = " cp $ p a t t e r n _ d i r / $dim_x [ $dim_x_idx ]$dim_y [ $dim_y_idx ] " . "$sim_time [ $ s i m _ t i m e_ i d x ] / m o b i l i t y $ n_ o f _ r un_ i d x / seed . t x t " . " $ p a t t e r n _ d i r / $dim_x [ $dim_x_idx ]$dim_y [ $dim_y_idx ] " . "$sim_time [ $ s i m _ t i m e_ i d x ] / s o ur ces$ n_ o f _ r un_ i d x / " ; p r i n t $command ; }

# generate pattern # p r i n t " \ t g ener at e p a t t e r n . . . \ n \ n " ; # topology # p r i n t " \ t \ tTOPPAT \ n " ; f o r ( $ p aus e_ t i m e_ i d x = 0 ; $ p aus e_ t i m e_ i d x < @pause_time ; $ p aus e_ t i m e_ i d x ++) { p r i n t " \ t \ tpause time : $pause_time [ $ p aus e_ t i m e_ i d x ] \ n " ; f o r ( $max_speed_idx = 0 ; $max_speed_idx < @max_speed ; $max_speed_idx ++) { p r i n t " \ t \ t \tmaximum speed : $max_speed [ $max_speed_idx ] \ n " ; f o r ( $ s c e n _ t y p e _ i d x = 0 ; $ s c e n _ t y p e _ i d x < @scen_type ; $ s c e n _ t y p e _ i d x ++) { p r i n t " \ t \ t \ t \ t s cen t y p e : $ s cen_ t y p e [ $ s c e n _ t y p e _ i d x ] \ n " ; # f i l e name $ f i l e_ nam e = " $ p a t t e r n _ d i r / $dim_x [ $dim_x_idx ]$dim_y [ $dim_y_idx ] " . "$sim_time [ $ s i m _ t i m e_ i d x ] / m o b i l i t y $ n_ o f _ r un_ i d x / scen$n_node [ $n_node_idx ] " . "$pause_time [ $ p aus e_ t i m e_ i d x]$max_speed [ $max_speed_idx ] " . "type@scen_type [ $ s c e n _ t y p e _ i d x ] " ; #Check i f f i l e e x i s t i f ( 1 = = e $ f i l e_ nam e ) { p r i n t " \ t \ t \ t \ t top : f i l e $ f i l e_ nam e e x i s t \ n " ; } else { p r i n t " \ t \ t \ t \ t top : g ener at e $ f i l e_ nam e \ n " ; my $command= " p e r l $topology_gen " .

143

A.3. Perl

"nn $n_node [ $n_node_idx ] " . "pause $pause_time [ $ p aus e_ t i m e_ i d x ] " . "speed $max_speed [ $max_speed_idx ] " . "simtime $sim_time [ $ s i m _ t i m e_ i d x ] " . "x $dim_x [ $dim_x_idx ] " . "y $dim_y [ $dim_y_idx ] " . "t y p e $ s cen_ t y p e [ $ s c e n _ t y p e _ i d x ] " . "seed $seed > $ f i l e_ nam e " ; p r i n t $command ; } # copy f i l e i n t o rem d i r my $command = " cp f $ f i l e_ nam e " . " $ p a c k e t _ p a t t e r n / $dim_x [ $dim_x_idx]$dim_y [ $dim_y_idx ] " . "$sim_time [ $ s i m _ t i m e_ i d x ] / m o b i l i t y $ n_ o f _ r un_ i d x " ; p r i n t $command ; } #s c e n t y p e }#max s p e e d }#pause #end movement # traffic # p r i n t " \ t \ tTRAPAT \ n " ; f o r ( $ s o u r c e _ t y p e _ i d x = 0 ; $ s o u r c e _ t y p e _ i d x < @source_type ; $ s o u r c e _ t y p e _ i d x ++) { p r i n t " \ t \ tsource type : $source_type [ $source_type_idx ] \ n " ; f o r ( $num_connect_idx = 0 ; $num_connect_idx < @num_connect ; $num_connect_idx ++) { p r i n t " \ t \ t \ tnumber o f co nnect i o ns : $num_connect [ $num_connect_idx ] \ n " ; f o r ( $ p a c k e t _ s i z e _ i d x = 0 ; $ p a c k e t _ s i z e _ i d x < @p acket _ s i z e ; $ p a c k e t _ s i z e _ i d x ++) { print " \ t \ t \ t \ tpacket_size : $packet_size [ $packet_size_idx ]\n" ; f o r ( $ p a c k e t _ r a t e _ i d x = 0 ; $ p a c k e t _ r a t e _ i d x < @packet_rate ; $ p a c k e t _ r a t e _ i d x ++) { p r i nt " \ t \ t \ t \ t \ tpacket_rate : $packet_rate [ $packet_rate_idx ] \ n" ; # out f i l e name $ f i l e_ nam e = " $ p a t t e r n _ d i r / $dim_x [ $dim_x_idx ]$dim_y [ $dim_y_idx ] " . "$sim_time [ $ s i m _ t i m e_ i d x ] / s o ur ces$ n_ o f _ r un_ i d x / " . " $ s o u r c e _ t y p e [ $ s o u r c e _ t y p e _ i d x ]$n_node [ $n_node_idx ] " . "$num_connect [ $num_connect_idx ] $ p a c k e t _ r a t e [ $ p a c k e t _ r a t e _ i d x] " . " $packet_size [ $packet_size_idx ] " ; # check i f f i l e e x i s t i f ( 1 = = e $ f i l e_ nam e ) { p r i n t " \ t \ t \ t \ t t r a f f i c : f i l e $ f i l e_ nam e a l r e a d y e x i s t \ n " ; } else { p r i n t " \ t \ t \ t \ t t r a f f i c : g ener at e $ f i l e_ nam e \ n " ; # System C a l l # my $command = " perl $traffic_gen " . "t y p e $ s o u r c e _ t y p e [ $ s o u r c e _ t y p e _ i d x ] " . "nn $n_node [ $n_node_idx ] " . "seed $seed " . "nc $num_connect [ $num_connect_idx ] " . "p k t s i z e $ p a c k e t _ s i z e [ $ p a c k e t _ s i z e _ i d x ] " . "r a t e $ p a c k e t _ r a t e [ $ p a c k e t _ r a t e _ i d x ] " . " > $ f i l e_ nam e " ; p r i n t $command ; } # copy f i l e i n t o rem d i r my $command = " cp f $ f i l e_ nam e " . " $ p a c k e t _ p a t t e r n / $dim_x [ $dim_x_idx ]$dim_y [ $dim_y_idx ] " .

144

A.3. Perl

"$sim_time [ $ s i m _ t i m e_ i d x ] / s o ur ces$ n_ o f _ r un_ i d x " ; p r i n t $command ; }#p a c k e t r a t e } #p a c k e t s i z e } #max c o n n e c t } #s o u r c e t y p e #end t r a f f i c }#s i mu l a ti on duration }# n o f nodes }#dim y } #dim x } #n o f run

p r i n t " \ n \ n ####################### GENERATE CONDOR F I L E ############ \ n \ n " ; # open f i l e t o w r i t e my $ co nd o r _ f i l enam e = " $ p a c k e t _ d i r / r u n _ s i m u l a t i o n . condor " ; open ( F I L E , " > $ co nd o r _ f i l enam e " ) ; # Open f o r out # w r i t e XXX . condor p r i n t F I L E "#CONDOR SUBMIT F I L E \ n " ; print FILE " # # # P r o j e c t : Semester P r o j e c t SS 05/06: # E v a l u a t i o n o f s c h e d u l i n g methods o v er m ul t i p at h # r o u t i n g i n w i r e l e s s mobile Ad Hoc networks # # Authors : Regula Goenner , Dominik Schatzmann # # [ condor f i l e auto generated ] # # # b u i l t by \ " c r e a t e _ s i m u l a t i o n . p l \ " p e r l s c r i p t ! # #START CONDOR universe getenv Rank = vanilla = True = Kflops

# Network S i m u l a t o r

needs l o c a l environment

# Problem : code i s compiled f o r l i n u x > use o nl y \ " LINUX \ " Requirements = ( ( Arch == \ " INTEL \ " | | Arch == \ " PPC \ " | | Arch == \ " x86_64 \ " | | " . " Arch == \ " ALPHA \ " | | Arch == \ " SUN4u \ " ) " . "&& ( OpSys == \ " LINUX \ " ) " . "&& Memory >=32 ) " . " #Only send a Email when Notification = Error # L e t j o b s run under T I K r i g h t s # ( . . . even i f I m a s t ud ent with o nl y I T E T r i g h t s +USER_GROUP = \ " t i k \ " +JOB_GROUP = \ " t i k \ " # executable F i l e e x e c u t a b l e = $rem_exe \n\n\n " ;

. . . ) ; )

my $ p r o c e s s p r i n t " \n\n " ;

= 0;

# counter of p r o c e s s e s

145

A.3. Perl

f o r ( $ n_ o f _ r un_ i d x = 0 ; $ n_ o f _ r un_ i d x < $n_of_run { p r i n t " run number : $ n_ o f _ r un_ i d x \ n " ;

; $ n_ o f _ r un_ i d x ++)

f o r ( $ q ueue_ t y p e_ i d x = 0 ; $ q ueue_ t y p e_ i d x < @queue_type ; $ q ueue_ t y p e_ i d x ++) { p r i n t " queue t y p e : $queue_type [ $ q ueue_ t y p e_ i d x ] \ n " ; f o r ( $ q ueue_ l eng t h_ i d x = 0 ; $ q ueue_ l eng t h_ i d x < @queue_length ; $ q ueue_ l eng t h_ i d x ++) { p r i n t " queue l eng t h : $queue_length [ $ q ueue_ l eng t h_ i d x ] \ n " ; f o r ( $dim_x_idx = 0 ; $dim_x_idx < @dim_x ; $dim_x_idx ++) { print " dimension x : $dim_x [ $dim_x_idx ] \ n " ; f o r ( $dim_y_idx = 0 ; $dim_y_idx < @dim_y ; $dim_y_idx ++) { print " dimension y : $dim_y [ $dim_y_idx ] \ n " ; f o r ( $n_node_idx = 0 ; $n_node_idx < @n_node ; $n_node_idx ++) { print " number o f nodes : $n_node [ $n_node_idx ] \ n " ; f o r ( $ s i m _ t i m e_ i d x = 0 ; $ s i m _ t i m e_ i d x < @sim_time ; $ s i m _ t i m e_ i d x ++) { print " s i m u l a t i o n d u r a t i o n : $sim_time [ $ s i m _ t i m e_ i d x ] \ n " ; f o r ( $ s i m _ p r o g r e s s _ i d x = 0 ; $ s i m _ p r o g r e s s _ i d x < @sim_progress ; $ s i m _ p r o g r e s s _ i d x ++) { print " s i m u l a t i o n p r o g r e s s time : $ s i m _ p r o g r es s [ $ s i m _ p r o g r e s s _ i d x ] \ n " ; f o r ( $ p aus e_ t i m e_ i d x = 0 ; $ p aus e_ t i m e_ i d x < @pause_time ; $ p aus e_ t i m e_ i d x ++) { print " pause time : $pause_time [ $ p aus e_ t i m e_ i d x ] \ n " ; f o r ( $max_speed_idx = 0 ; $max_speed_idx < @max_speed ; $max_speed_idx ++) { print " maximum speed : $max_speed [ $max_speed_idx ] \ n " ; f o r ( $ s o u r c e _ t y p e _ i d x = 0 ; $ s o u r c e _ t y p e _ i d x < @source_type ; $ s o u r c e _ t y p e _ i d x ++) { print " s o ur ce t y p e : $ s o u r c e _ t y p e [ $ s o u r c e _ t y p e _ i d x ] \ n " ; f o r ( $num_connect_idx = 0 ; $num_connect_idx < @num_connect ; $num_connect_idx ++) { print " num_connections : $num_connect [ $num_connect_idx ] \ n " ; f o r ( $ p a c k e t _ s i z e _ i d x = 0 ; $ p a c k e t _ s i z e _ i d x < @p acket _ s i z e ; $ p a c k e t _ s i z e _ i d x ++) { print " packet_size : $packet_size [ $packet_size_idx ]\n" ; f o r ( $ p a c k e t _ r a t e _ i d x = 0 ; $ p a c k e t _ r a t e _ i d x < @packet_rate ; $ p a c k e t _ r a t e _ i d x ++) { print " packet_rate : $packet_rate [ $packet_rate_idx ] \ n" ; f o r ( $ s ched _ t y p e_ i d x = 0 ; $ s ched _ t y p e_ i d x < @sched_type ; $ s ched _ t y p e_ i d x ++) { print " s ched _ t y p e : $ s ched _ t y p e [ $ s ched _ t y p e_ i d x ] \ n " ; f o r ( $max_path_idx = 0 ; $max_path_idx < @max_path ; $max_path_idx ++) { print " max_path : $max_path [ $max_path_idx ] \ n " ; f o r ( $ s c e n _ t y p e _ i d x = 0 ; $ s c e n _ t y p e _ i d x < @scen_type ; $ s c e n _ t y p e _ i d x ++) { print " s cen_ t y p e ( pat ) : $ s cen_ t y p e [ $ s c e n _ t y p e _ i d x ] \ n " ; p r i n t ( " condor f i l e c h e c k : " , s " $sim_data " . "r i $ n_ o f _ r un_ i d x " . "qt$ q ueue_ t y p e_ i d x " . "ql$queue_length [ $ q ueue_ l eng t h_ i d x ] " . "dx$dim_x [ $dim_x_idx ] " . "dy$dim_y [ $dim_y_idx ] " . "nn$n_node [ $n_node_idx ] " . "sd$sim_time [ $ s i m _ t i m e_ i d x ] " . "sp$ s i m _ p r o g r es s [ $ s i m _ p r o g r e s s _ i d x ] " . "pt$pause_time [ $ p aus e_ t i m e_ i d x ] " . "ms$max_speed [ $max_speed_idx ] " . "scp$ s cen_ t y p e [ $ s c e n _ t y p e _ i d x ] " . "s t$ s o u r c e _ t y p e [ $ s o u r c e _ t y p e _ i d x ] " . "mc$num_connect [ $num_connect_idx ] " . "ps$ p a c k e t _ s i z e [ $ p a c k e t _ s i z e _ i d x ] " .

146

A.3. Perl

"pr$ p a c k e t _ r a t e [ $ p a c k e t _ r a t e _ i d x ] " . "sc$ s ched _ t y p e [ $ s ched _ t y p e_ i d x ] " . "pn$max_path [ $max_path_idx ] . sim " , " \ n " ) ; #Check i f d a t a p o i n t ( . sim ) a l l r e a d y e x i s t s i f (( s " $sim_data " . "r i $ n_ o f _ r un_ i d x " . "qt$ q ueue_ t y p e_ i d x " . "ql$queue_length [ $ q ueue_ l eng t h_ i d x ] " . "dx$dim_x [ $dim_x_idx ] " . "dy$dim_y [ $dim_y_idx ] " . "nn$n_node [ $n_node_idx ] " . "sd$sim_time [ $ s i m _ t i m e_ i d x ] " . "sp$ s i m _ p r o g r es s [ $ s i m _ p r o g r e s s _ i d x ] " . "pt$pause_time [ $ p aus e_ t i m e_ i d x ] " . "ms$max_speed [ $max_speed_idx ] " . "scp$ s cen_ t y p e [ $ s c e n _ t y p e _ i d x ] " . "s t$ s o u r c e _ t y p e [ $ s o u r c e _ t y p e _ i d x ] " . "mc$num_connect [ $num_connect_idx ] " . "ps$ p a c k e t _ s i z e [ $ p a c k e t _ s i z e _ i d x ] " . "pr$ p a c k e t _ r a t e [ $ p a c k e t _ r a t e _ i d x ] " . "sc$ s ched _ t y p e [ $ s ched _ t y p e_ i d x ] " . "pn$max_path [ $max_path_idx ] . sim " ) = = 0 ) { # . sim doesn t e x i s t > s i m u l a t e d a t a p o i n t p r i n t F I L E #change out t o f i l e " #JOB NUMBER : \ t $ p r o c e s s \ n arguments = $ v e r s i o n" . #name o f sim f i l e " r i $ n_ o f _ r un_ i d x" . " qt$queue_type_idx " . " ql$queue_length [ $ q ueue_ l eng t h_ i d x ] " . " dx$dim_x [ $dim_x_idx ] " . " dy$dim_y [ $dim_y_idx ] " . " nn$n_node [ $n_node_idx] " . " sd$sim_time [ $ s i m _ t i m e_ i d x] " . " sp$ s i m _ p r o g r es s [ $ s i m _ p r o g r e s s _ i d x] " . " pt$pause_time [ $ p aus e_ t i m e_ i d x] " . "ms$max_speed [ $max_speed_idx] " . " scp$ s cen_ t y p e [ $ s c e n _ t y p e _ i d x] " . " s t$ s o u r c e _ t y p e [ $ s o u r c e _ t y p e _ i d x ] " . "mc$num_connect [ $num_connect_idx ] " . " ps$ p a c k e t _ s i z e [ $ p a c k e t _ s i z e _ i d x ] " . " pr$ p a c k e t _ r a t e [ $ p a c k e t _ r a t e _ i d x] " . " sc$ s ched _ t y p e [ $ s ched _ t y p e_ i d x ] " . " pn$max_path [ $max_path_idx ] " . #remote exe " $ r em _ s t ar t _ ns " . #t o p o l o g y " p a t t e r n / $dim_x [ $dim_x_idx ]$dim_y [ $dim_y_idx ]$sim_time [ $ s i m _ t i m e_ i d x ] / " . " m o b i l i t y $ n_ o f _ r un_ i d x / scen$n_node [ $n_node_idx] " . " $pause_time [ $ p aus e_ t i m e_ i d x]$max_speed [ $max_speed_idx ] " . " type@scen_type [ $ s c e n _ t y p e _ i d x ] " . #traffic " p a t t e r n / $dim_x [ $dim_x_idx ]$dim_y [ $dim_y_idx ]$sim_time [ $ s i m _ t i m e_ i d x ] / " . " s o ur ces$ n_ o f _ r un_ i d x / $ s o u r c e _ t y p e [ $ s o u r c e _ t y p e _ i d x ] " . " $n_node [ $n_node_idx]$num_connect [ $num_connect_idx ] " . " $ p a c k e t _ r a t e [ $ p a c k e t _ r a t e _ i d x] $ p a c k e t _ s i z e [ $ p a c k e t _ s i z e _ i d x ] " . # other parameters . . . " $queue_type [ $ q ueue_ t y p e_ i d x ] " . " $queue_length [ $ q ueue_ l eng t h_ i d x ] " . " $dim_x [ $dim_x_idx ] " .

# queue t y p e # queue l e n g t h # dimension x

147

A.3. Perl

" $dim_y [ $dim_y_idx ] " . # dimension y " $n_node [ $n_node_idx ] " . # number o f nodes " $sim_time [ $ s i m _ t i m e_ i d x ] " . # simulation duration " $ s i m _ p r o g r es s [ $ s i m _ p r o g r e s s _ i d x ] " . # simulation progress " $ s ched _ t y p e [ $ s ched _ t y p e_ i d x ] " . # scheduler type " $max_path [ $max_path_idx ] " . # max number o f p a t h s # where t o s a v e t h e l o g f i l e s " \n log = co nd o r _ l o g / condor . l o g out = co nd o r _ l o g / out / $ p r o c e s s error = co nd o r _ l o g / e r r o r / $ p r o c e s s queue \ n \ n " ; $process ++; } }# scen_type } # aomdv max path }# scheduler type }# p a c k e t r a t e }# p a c k e t s i z e } # max c o n n e s t i o n }# source type } # max s p e e d } # pause time }# simulation progress }# s i m u l a t i o n d u r a t i o n }# n o f nodes } # dim y } # dim x } # queue l e n g t h } # queue t y p e }# run close ( FILE ) ; chdir " $out_dir " ; # t a r f o l d e r and upload pr int " tar folder . . . \n" ; p r i n t t a r c z v f t r a n s i t _ $ v e r s i o n$ t e s t s e r i e s . gz . t a r $ v e r s i o n $ t e s t s e r i e s ; p r i n t ( " upload to I T E T ? to $ r em o t e_ ho s t _ d i r \ n ( Y /N ) \ n " ) ; my $ i np ut = <STDIN > ; chomp $ i np ut ; i f ( $ i np ut eq Y | | $ i np ut eq y ) { p r i n t ( " Warning : Sometimes scp s t o p s ! ? ! . . . ssh bug ? \ n " ) ; scp t r a n s i t _ $ v e r s i o n$ t e s t s e r i e s . gz . t a r $user_name \ @$remote_host : $ r em o t e_ ho s t _ d i r ; # decompress f o l d e r p r i n t " Decompress t a r on I T E T to $ i np ut = <STDIN > ; chomp $ i np ut ; i f ( $ i np ut eq Y | | $ i np ut eq y ) { my $command= " ssh $user_name \ @$remote_host " . " t a r x z v f $ r em o t e_ ho s t _ d i r / t r a n s i t _ $ v e r s i o n$ t e s t s e r i e s . gz . t a r " . "d i r e c t o r y $ r em o t e_ ho s t _ d i r " ; p r i n t $command ; } }

$ r em o t e_ ho s t _ d i r ? \ n Y /N\ n " ;

148

A.3. Perl

p r i n t " \ n \ n Master , I f i n i s h e d my work \ n\ n " ;

Listing A.9: create_simulation.pl

149

A.3. Perl

A.3.4. remote.pl
#! / usr / bin / p e r l # # REMOTE . PL f i l e t o b u i l d condor submit f i l e # # P r o j e c t : S e m e s t e r T h e s i s S S 06: # E v a l u a t i o n o f s c h e d u l i n g methods o v e r # m u l t i p a t h r o u t i n g i n w i r e l e s s m o b i l e Ad Hoc n e t w o r k s # # A u t h o r s : R e gu l a Goenner , Dominik Schatzmann # # [ Perl Script ] # # Date : J u l y 2006 # # Input : # [ none ] # Output : # # # # # S c r i p t i s e x e c u t e d on t h e remote h o s t # # Behave l i k e a r e a s o n a b l e programming language use s t r i c t ; print print print print print " \ n\ n " ; "############################### "# remote s c r i p t s s t a r t e d "# remote . p l "###############################

\n " \n " \n " \n "

; ; ; ;

p r i n t " \ n\ n parameter l i s t \n " ; my my my my my my my my my my my my my $name_of_process $tcl_script $move_pattern $traffic_pattern $queue_type $queue_length $dimension_x $dimension_y $number_of_node $sim_time $ s i m _ p r o g r es s $ s ched _ t y p e $aomdv_max_path = = = = = = = = = = = = = $ARGV [ 0 ] ; $ARGV [ 1 ] ; $ARGV [ 2 ] ; $ARGV [ 3 ] ; $ARGV [ 4 ] ; $ARGV [ 5 ] ; $ARGV [ 6 ] ; $ARGV [ 7 ] ; $ARGV [ 8 ] ; $ARGV [ 9 ] ; $ARGV [ 1 0 ] ; $ARGV [ 1 1 ] ; $ARGV [ 1 2 ] ;

#c o u t print print print print print print print print print print print print print

parameter ( v i s u a l f e e d b a c k c h e c k ) " name o f p r o c e s s : \ t \ t $name_of_process \ n " ; " name o f t c l s c r i p t : \ t \ t $ t c l _ s c r i p t \n" ; " name o f movement p a t t e r n : \ t \ t $move_pattern \ n " ; " name o f t r a f f i c p a t t e r n : \ t \ t $ t r a f f i c _ p a t t e r n \ n " ; " t y p e o f i n t e r f a c e queue : \ t \ t $queue_type \ n " ; " l eng t h o f i n t e r f a c e queue : \ t \ t $queue_length \ n " ; " dimension x : \ t \ t $dimension_x \ n " ; " dimension y : \ t \ t $dimension_y \ n " ; " number o f nodes : \ t \ t $number_of_node \ n " ; " simulation duration : \ t \ t $sim_time \ n " ; " simulation progress : \ t \ t $ s i m _ p r o g r es s \ n " ; # unused . . . " scheduling type : \ t \ t $ s ched _ t y p e \ n " ; "max number o f paths \ t \ t $aomdv_max_path \ n " ;

p r i n t " s t a r t NS . . . \ n \ n " ;

150

A.3. Perl

# # # s t a r t NS and s e t working p a t h s # # my $command = " echo \ " s e t path \ " ; " . " ex p o r t PATH=\$HOME/ nssmall 2.26/ b i n : " . " \$HOME/ nssmall 2.26/ t c l 8 . 3 . 2 / unix : " . " \$HOME/ nssmall 2.26/ t k8 . 3 . 2 / unix : " . " \ $PATH ; " . " ex p o r t TCL_LIBRARY =\$HOME/ nssmall 2.26/ t c l 8 . 3 . 2 / l i b r a r y ; " . " ex p o r t LD_LIBRARY_PATH = \ " \$HOME/ nssmall 2.26/ l i b : " . " \$HOME/ nssmall 2.26/ o t c l 1.0 a8 \ " ; " . " echo \ " s t a r t NS \ " ; " . " . / ns $ t c l _ s c r i p t sim_data / $name_of_process $move_pattern " . " $ t r a f f i c _ p a t t e r n $queue_type $queue_length $dimension_x " . " $dimension_y $number_of_node $sim_time $ s i m _ p r o g r es s " . " $ s ched _ t y p e $aomdv_max_path " ; p r i n t ( $command ) ; # # # p r o c e s s output data # # # Due t o TCL 2 . 0 GB f i l e s i z e bug , t h e data a r e p r e c e s s e d on t h e f l y # T h i s i s implemented i n t h e aomdv . t c l # # # finishing # # # wait u n t i l gawk has f i n i s h e d h i s j o b p r i n t ( " check i f gawk has f i n i s h e d h i s jo b . . . \ n " ) ; my $ t r i g g e r = 1 ; my $time_out = 6 ; w hi l e ( $ t r i g g e r ) { i f ( z " sim_data / $name_of_process . sim " ) #c h e c k f i l e s i z e { # f i l e has z e r o s i z e # j u s t wait . . . p r i n t " gawk i s s t i l l working \ n " ; i f ( $time_out <= 0) #problems ? { p r i n t " time_out . . . s t o p s i m u l a t i o n $ t r i g g e r = 0; } else { $time_out = $time_out 1 ; sleep ( 1 0 ) ; } } else {

. . . \ n" ;

151

A.3. Perl

# gawk p r o c e s s i s f i n i s h e d p r i n t " gawk has f i n i s h e d h i s jo b " ; $ t r i g g e r = 0; sleep ( 1 0 ) ; } } p r i n t " \ nnext jo b p l e a s e

. . . \n"

Listing A.10: remote.pl

152

A.3. Perl

A.3.5. analysis_one_run.pl
#! / usr / bin / p e r l # # ANALYSIS_ONE_RUNS . PL F I L E TO GENERATE ANALYSE ONE . SIM F I L E # # P r o j e c t : S e m e s t e r T h e s i s S S 06: # E v a l u a t i o n o f s c h e d u l i n g methods o v e r # m u l t i p a t h r o u t i n g i n w i r e l e s s m o b i l e Ad Hoc n e t w o r k s # # A u t h o r s : R e gu l a Goenner , Dominik Schatzmann # # [ Perl Script ] # # Date : J u l y 2006 # # I n p u t : [ f i l e SIMF I L E ] # # # Output : g r a p h i c s i n e p s format # # # Idea : # T h i s s c r i p t s shows d i f f e r e n t i n f o r m a t i o n about t h i s ( sim ) run # show t h e number o f found p a t h s a t t h e s o u r c e o v e r t h e # time f o r one c o n n e c t i o n # c a l c u l a t e t h e a v e r a ge number o f p a t h s f o r a l l c o n n e c t i o n s # shows a l l p a t h s from s o u r c e t o d e s t i n a t i o n # # # Concept : # 1 . Read i n t h e i n f o r m a t i o n o f one . sim f i l e # 2 . C a l c u l a t e a l l needed v a r i a b l e s f o r t h e s t a t i s t i c # time d i s c r e t i s a t i o n based on e v e n t s ( time s l o t s ) # c a l c u l a t e t h e a c t i v e p a t h s f o r each time s l o t # 3 . C a l c u l a t e the s t a t i s t i c s # number o f found path on a v e r a ge f o r each c o n n e c t i o n # 4 . Menu t o s e l e c t which i n f o r m a t i o n s h o u l d be d i s p l a y e d # # I m p l e m e n t a t i on : # # sub a r gu m e n t _ p a r sin g f e t c h arguments o f t h e command l i n e # # sub menu user i n t e r f a c e # # sub i m p o r t _ d a t a r e a d data out o f . sim f i l e i n t o hash t a b l e s # # sub number_sort helper function for sort ( ) function c a l l # # sub c a l c u l a t e _ s t a t _ r t _ s _ t c a l c u l a t e a l l needed i n f o r m a t i o n based on # t h e r o u t i n g t a b l e s p a c e time ( path ) # number o f p a t h s a t time X # number o f p a t h s i n avg # number o f p a t h s found i n r o u t i n g t a b l e # from s o u r c e t o d e s t i n a t i o n a t time X # # sub c a l c u l a t e _ s t a t _ r t _ s r c c a l c u l a t e a l l needed i n f o r m a t i o n based on # t h e r o u t i n g t a b l e s o u r c e t >180 # number o f p a t h s i n avg # max number o f p a t h s o v e r time # number o f p a t h s found by one r o u t e r e q u e s t # # sub sub dropzone p l o t s t h e number o f dropped / s e n t p a c k e t i n an a r e a # # sub c a l c _ s t a t _ s h o r t e s t c a l c u l a t e a l l s t a t i s t i c s based on t h e s h o r t e s t path # # sub c a l c _ s t a t _ s h o r t e s t _ c o n n e c t i o n : d i s t r i b u t i o n o f s h o r t e s t path # in th i s simulation

153

A.3. Perl

# sub c a l c _ s t a t _ 1 8 0 _ t i m e : avg found path o v e r time # v e r s u s s h o r t e s t path # sub c a l c _ s t a t _ 1 8 0 _ r p _ p : avg found path f o r one RREQ # v e r s u s s h o r t e s t path # sub p l o t _ p a t h _ s h o r t e s t : p l o t s the s t a t i s t i c over s h o r t e s t paths # # sub c o n n e c t i o n _ i n f o u s e r i n t e r f a c e f o r one c o n n e c t i o n # sub show_path : shows a l l a c t i v e p a t h s d u r i n g t h e # s i m u l a t i o n as t e x t # sub make_movie : makes an animated g i f out o f # t h e path i n f o r m a t i o n # sub make_movie_short : g e n e r a t e s an animated g i f out o f # a s u b s et of the s i m u l a ti o n # sub p l o t _ p a t h _ t i m e : p l o t s t h e number o f found p a t h s # f o r one c o n n e c t i o n o v e r time # sub p l o t _ p a t h _ s p a c e : p l o t s t h e path i n s p a c e # # use s t r i c t ; # # # global va ri a b l es # # # s w i t c h DEBUG OUTPUT on / o f f my $DEBUG = 0; # path o f w h i r l g i f ( make animated g i f ) my $ w h i r l g i f = " /home/ alpha / sa / svnd i r / t r unk / So ur ces / w h i r l g i f / w h i r l g i f " ; # f o l d e r t o s a v e t e m p o r a l data f i l e s my $ f o l d er _ t em p = " temp " ; mkdir $ f o l d er _ t em p ; # . sim f i l e with t h e s t a t i s t i c ( ARG ) my $ s i m _ f i l e = " " ; # DATA CONTAINER # # based o f . sim f i l e # s i m u l a t i o n end # # # ! ! ! Assumption s i m u l a t i o n end = l a s t data p a c k e t s e n t # # my $ s i m ul at i o n_ end = 0; # number o f nodes my $ n o d e _ t o t a l # p o s i t i o n o f nodes my @position_x_node my @position_y_node

= 0;

= (); = ();

# dropped p a c k e t my @dropped_packet_data_node my $ d r o p p e d _ p a c k e t _ d a t a _ t o t a l

= (); = 0;

my @d r o p p ed _ d p acket s_ v _ tot_ sent =(); my @dropped_dpackets_v _ received_ node =(); # sent packet my @sent_packet_data_node my $ s e n t _ p a c k e t _ d a t a _ t o t a l

= (); = 0;

154

A.3. Perl

# rec ei ved packet my @r ecei v ed _ p acket _ d at a_ nod e my $ r e c e i v e d _ p a c k e t _ d a t a _ t o t a l # forwarded packet my @forwarded_packet_data_node # ratio : my $ d a t a _ d e l i v e r y _ r a t i o

= (); = 0;

= ();

= 0;

# c h e c k i f t r a c e was c o m p l e t e my $ d a t a _ p a c k e t _ f i r s t _ t i m e =0; my $ d a t a _ p a c k e t _ l a s t _ t i m e =0;

# based on r t _ s _ t # d a t a b a s e with a l l data c o n n e c t i o n s my %s r c _ d e s t # $ s r c _ d e s t { " num con " } # $src_dest { $src }{ $dst } # $ s r c _ d e s t {# c o n n e c t i o n _ i n d e x } { " s r c " } # $ s r c _ d e s t {# c o n n e c t i o n _ i n d e x } { " d s t " }

= = = = =

(); # number o f c o n n e c t i o n s (1 xx ) $connection_index ; $src ; $dst ;

# d a t a b a s e with a l l p a t h s o f t h e data c o n n e c t i o n s my %s r c _ d e s t _ p a t h =(); # $ s r c _ d e s t _ p a t h { $ s r c } { $ d s t } { " num p a t h s " } = #number o f p a t h s # $ s r c _d es t _p a t h { $ s r c } { $ d s t } { $path_index } = $path ; # $ s r c _ d e s t _ p a t h { $ s r c } { $ d s t } { $path } = $path_index ; # timeline discr etisation my @timeline_up =(); # $timeline_up [ $s rc ] [ $dst ] = [ s o r t ( number_sort @timeline_up_temp ) ] ; # > R e f on a r r a y . . . use @{ R e f } t o a c c e s s data my @timeline_down =(); # $timeline_down [ $ s r c ] [ $ d s t ] = [ s o r t ( number_sort @timeline_down_temp ) ] ; # > R e f on a r r a y . . . use @{ R e f } t o a c c e s s data # event database my %event_hash =();

# $ e v e n t _ h a s h { $ s r c } { $ d s t } { " up " } { $uptime } { " num e v e n t s " } = number o f e v e n t s a t time x # $ e v e n t _ h a s h { $ s r c } { $ d s t } { " up " } { $uptime } { # e v e n t } = $path # $ e v e n t _ h a s h { $ s r c } { $ d s t } { " down " } { $downtime } { " num e v e n t s " } = number o f e v e n t s a t time x # $ e v e n t _ h a s h { $ s r c } { $ d s t } { " down " } { $downtime } { # e v e n t } = $path # based on r t _ s r c # what t h e s o u r c e saw my %p at h_ t i m e_ s r c =(); #$ p a t h _ t i m e _ s r c { $ s r c } { $ d s t } { " s h o r t e s t path " } = l e n g t h o f s h o r t e s t p a t h s o f t h i s s r c d e s t #$ p a t h _ t i m e _ s r c { $ s r c } { $ d s t } { " num s l o t s " } = Number o f time time s l o t s #$ p a t h _ t i m e _ s r c { $ s r c } { $ d s t } { # s l o t } { " time " } = r e a l time o f t h i s time s l o t #$ p a t h _ t i m e _ s r c { $ s r c } { $ d s t } { # s l o t } { " num p a t h s " } = number o f a c t i v e p a t h s a t t h i s time s l o t

# CALCULATED DATA s # my %p at h_ t i m e_ s _ t = ( ) ; # P a t h s o v e r t h e time based on r o u t i n g t a b l e i n f o s # $ p a t h _ t i m e { $ s r c } { $ d s t } { " num s l o t s " } ;

155

A.3. Perl

my @p at h_ t i m e_ s _ t _ act i v e_ p at hs = ( ) ; # a c t i v e p a t h s a t # s l o t # p a t h _ t i m e _ s _ t _ a c t i v e _ p a t h s [ $ s r c ] [ $ d s t ] [ # s l o t ] = r e f > a r r a y with a c t i v e p a t h s # r o u t i n g p r o t o c o l performance data c o n t a i n e r my @rp_performace = ( ) ; #$ r p _ p e r f o r m a n c e [# s h o r t e s t path ] [ # number o f found p a t h s ] = $ c o u n t e r #$ r p _ p e r f o r m a n c e [# s h o r t e s t path ] [ 0 ] = $ t o t a l _ c o u n t e r

# S T A T I S T I C CONTAINER # my %p a t h _ s h o r t e s t = ( ) ; # ave p a t h s found f o r t h i s s h o r t e s t path

# # # main # # print " # \n SEMESTER PROJECT ( SS 0 6 ) : TITLE : E v a l u a t i o n o f s c h e d u l i n g methods o v er m ul t i p at h r o u t i n g i n w i r e l e s s mobile Ad Hoc networks AUTHOR : Regula Goenner [ rgoenner \@ee . et hz . ch ] Dominik Schatzmann [ schadomi \@ee . et hz . ch ] TUTOR : G eo r g i o s P a r i s s i d i s \n # \n " ; print print print print " " " " \n " ; # #\n " ; # S c r i p t BOX V e r s i o n 001 #\n " ; # #\n " ;

argument_parsing ( ) ; p r i n t f ( " import data o f . sim f i l e import_data ( ) ; printf ( " calculate s t a t i st ic s . . . \ n" ) ;

. . . \ n" ) ; $ i i ++)

f o r (my $ i i = 1 ; $ i i <= $ s r c _ d e s t { "num con " } ; { p r i n t f ( " \ t co nnect i o n %i \ n " , $ i i ) ; calculate_stat_rt_s_t ( $i i ) ; calculate_stat_rt_src ( $i i ) ; } calc_stat_shortest ( ) ; menu ( ) ;

# # # subfunctions # # sub argument_parsing { # r e a d arguments i n t o v a r i a b l e s i f ( s c a l a r ( @ARGV) ! = 2 ) {

156

A.3. Perl

d i e ( " use : f i l e [ SIM F I L E ] \ n " ) ; } i f ( $ARGV [ 0 ] eq " f i l e " ) { $ s i m _ f i l e = $ARGV [ 1 ] ; } else { d i e ( " $ARGV [ 1 ] i s not a v a l i d i np ut parameter \ n " ) } } sub menu { # Us e r I n t e r f a c e my $menu = 1 ; w hi l e ( $menu ) { p r i n t " \n\n " ; print " p r i n t " | MENU | print " print print print print print print print print

\n " ; \n " ; \n " ;

" F i l e : $ s i m _ f i l e \n " ; " D e l i v e r y r a t i o ( r e c e i v e d / s ent data p a c k e t s ) : $ d a t a _ d e l i v e r y _ r a t i o \ n " ; " \n " ; " CHOOSE : \ n " ; " I n f o r m a t i o n o v er one co nnect i o n ( submenu ) 1\n" ; " I n f o r m a t i o n o v er a l l co nnect i o ns ( submenu ) 2\n " ; " L i s t a l l co nnect i o ns ( submenu ) 3\n " ; " E XI T 0\n " ;

$menu = <STDIN > ; chomp $menu ; i f ( $menu == 1 ) { # one c o n n e c t i o n p r i n t f ( " Connection number ? \ n " ) ; my $ co nnect i o n_ =0; $ co nnect i o n_ = <STDIN > ; chomp $ co nnect i o n_ ; i f ( $ co nnect i o n_ > 0 && $ co nnect i o n_ <= $ s r c _ d e s t { "num con " } ) { c o n n e c t i o n _ i n f o ( $ co nnect i o n_ ) ; } } e l s i f ( $menu == 2 ) { # a l l connections my $menu_all = 1 ; w hi l e ( $menu_all ) { p r i n t " \n\n" ; p r i n t " ## ALL CONNECTIONS ### \ n " ; print " # " ; p r i n t " \n " ; p r i n t " Number o f found paths per l i n k ( normal s i m u l a t i o n ) 1 \ n " ; p r i n t " Dropzone 2\n " ; p r i n t " RETURN 0\n " ; $menu_all = <STDIN > ; chomp $menu_all ; i f ( $menu_all == 1 ) { #Number o f found p a t h s p e r l i n k

157

A.3. Perl

plot_path_shortest ( ) ; } e l s i f ( $menu_all == 2 ) { #Dropzone dropzone ( ) ; } e l s i f ( $menu_all == 0) { #RETURN } else { p r i n t " unknown menu : $menu_all \ n " ; } } } e l s i f ( $menu == 3 ) { # Display a l l connections p r i n t f ( " \ nCONNECTIONS t o t a l : %s \ n " , $ s r c _ d e s t { "num con " } ) ; f o r ( my { my my my $ii = 1; $ i i <= $ s r c _ d e s t { "num con " } ; $ i i ++)

$src $dst $shortest_path

= $src_dest { $ i i } { " src " } ; = $s r c_des t { $ i i } { " dst " } ; = $ p at h_ t i m e_ s r c { $ s r c } { $ d s t } { " s h o r t e s t path " } ; \ t Dest : %i $dst , \ t S h o r t e s t path : %i $shortest_path ) ; \n " ,

p r i n t f ( "NR %i $ii ,

\ t S r c : %i $src ,

} } e l s i f ( $menu == 0) { # end $menu=0 } else { #unknown parameter p r i n t " unknown menu : $menu\ n " ; } } #w h i l e $menu }# END sub menu sub import_data { # r e a d data out o f . sim f i l e #local variable my @l i nes = (); my $ l i n e = 0; my @elements = (); # l o o p v a r i a b l e o v e r a l l nodes my $node_index = 0 ; # open sim f i l e open ( SI M_ F I L E , " < $ s i m _ f i l e " ) o r d i e " Couldn t open # read f i l e i n t o array @lines ( @l i nes ) = < SI M_ F I L E > ; f o r e a c h $ l i n e ( @l i nes ) # f o r each l i n e { # s p l i t l i n e i n elements @elements = s p l i t ( / / , $ l i n e ) ; # p a r s e each l i n e i f ( ( $elements [ 0 ] =~ m/ ( 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 ) / ) {

$ s i m _ f i l e \n " ;

&& ( s c a l a r ( @elements ) > 3 )

158

A.3. Perl

# node l i n e # s e n t data p a c k e t $ s ent _ p acket _ d at a_ no d e [ $node_index ] $sent_packet_data_total # r e c e i v e d data p a c k e t ( AG ) $ r ecei v ed _ p a c k et _ d a t a _ n o d e [ $node_index ] $received_packet_data_total # f o r w a r d e d data p a c k e t ( RTR ) $forwarded_packet_d ata_ node [ $node_index ] # dropped data p a c k e t $dropped_packet_data_node [ $node_index ] $dropped_packet_data_total # node p o s i t i o n $ p o s i t i o n_ x _ no d e [ $node_index ] $ p o s i t i o n _ y _ n o d e [ $node_index ] # i n c r e m e n t node c o u n t e r $node_index + + ; $ n o d e _ t o t a l=$node_index ; } e l s i f ( $elements [ 0 ] =~ / RATIO / ) { # d e l i v e r e d data $ d a t a _ d e l i v e r y _ r a t i o = $elements [ 1 ] ; } i f ( $elements [ 0 ] =~ / f i r s t data with i d / && s c a l a r ( @elements ) < 8 ) { # f i r s t data p a c k e t s e n t $ d a t a _ p a c k e t _ f i r s t _ t i m e = $elements [ 3 ] ; } i f ( $elements [ 0 ] =~ / l a s t data with i d / && s c a l a r ( @elements ) < 8 ) { # l a s t data p a c k e t s e n t $ d a t a _ p a c k e t _ l a s t _ t i m e = $elements [ 3 ] ; # ASSUMPTION $ s i m ul at i o n_ end = $ d a t a _ p a c k e t _ l a s t _ t i m e ; } e l s i f ( $elements [ 0 ] =~ "#RTHST " ) { # r o u t i n g t a b l e s p a c e time header #print ( $ li n e ) ; } e l s i f ( $elements [ 0 ] =~ #RTST ) { # r o u t i n g t a b l e s p a c e time data # interface definition my $ s r c = $elements [ 1 ] ; my $ d s t = $elements [ 2 ] ; my $path_number = $elements [ 3 ] ; my $path = $elements [ 4 ] ; my $up = $elements [ 5 ] ; my $down = $elements [ 6 ] ;

= $elements [ 3 ] ; += $elements [ 3 ] ;

= $elements [ 5 ] ; += $elements [ 5 ] ;

= $elements [ 6 ] ;

= $elements [ 8 ] ; += $elements [ 8 ] ;

= $elements [ 1 ] ; = $elements [ 2 ] ;

# t e m p o r a l a r r a y t o c o n s t r u c t time l i n e my @timeline_down_temp = ();

159

A.3. Perl

i f ( $DEBUG == 1 ) { # parse check print ( " src : $src \ t " ) ; p r i n t ( " d es t : $ d s t \ t " ) ; p r i n t ( " path_number : $path_number \ t " ) ; p r i n t ( " path : $path \ t " ) ; p r i n t ( " up : $up \ t " ) ; p r i n t ( " down $down\ t " ) ; p r i n t ( " \n " ) ; } i f ( $path_number=~ m/ ( 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 ) / ) { # c o l l e c t a l l source d es ti n a ti o n connections # # i f ( $ s r c _ d e s t { $ s r c } { $ d s t }== " " ) { # new c o n n e c t i o n # update t o t a l data c o n n e c t i o n c o u n t e r $ s r c _ d e s t { "num con " } + + ; my $ co nnect i o n_ i n d e x = $ s r c _ d e s t { "num con " } ; # s a v e new c o n n e c t i o n i n hash t a b l e $s r c_ d es t { $s r c } { $dst } = $ co nnect i o n_ i nd ex ; $ s r c _ d e s t { $ co nnect i o n_ i n d e x } { " s r c " } = $ s r c ; $ s r c _ d e s t { $ co nnect i o n_ i n d e x } { " d s t " } = $ d s t ; p r i n t f ( " PARSE CONNECTION : NUM: %s \ t SRC : %s \ t DEST : %s \ n " , $ co nnect i o n_ i nd ex , $ s r c , $ d s t ) ; } # c o l l e c t a l l path ( with a hash number ) # # i f ( $ s r c _ d e s t _ p a t h { $ s r c } { $ d s t } { $path }== " " ) { # new path $ s r c _ d e s t _ p a t h { $ s r c } { $ d s t } { "num paths " } + + ; my $ p at h_ i nd ex = $ s r c _ d e s t _ p a t h { $ s r c } { $ d s t } { "num paths " } ; $ s r c _ d e s t _ p a t h { $ s r c } { $ d s t } { $ p at h_ i nd ex } = $path ; $ s r c _ d e s t _ p a t h { $ s r c } { $ d s t } { $path } = $ p at h_ i nd ex ; i f ( $DEBUG == 1 ) { p r i n t f ( " \ t \ tPATH : NUM: %s \ t PATH : %s \ n " , $path_index , $path ) ; } } else { #o l d path ! d i e ( " import data : c o l l e c t path : path a l r e a d y s t o r e d ! ! ERROR ! ! ! " ) ; } # p r o c e s s up time e v e n t s # # # t e m p o r a l a r r a y t o c o n s t r u c t time l i n e my @timeline_up_temp = (); # c o n t a i n e r s t o work with up and down t i m e s my @uptimes = ( ) ; my $uptime = 0 ;

160

A.3. Perl

# load t i m e l i n e # i f ( $ t i m e l i n e _ u p [ $ s r c ] [ $ d s t ] == " " ) {# f i r s t path > new @timeline_up_temp = ( ) ; } else {# l o a d o l d time l i n e @timeline_up_temp = @{ $ t i m e l i n e _ u p [ $ s r c ] [ $ d s t ] } ; } # l o a d uptimes @uptimes = s p l i t ( / / , $up ) ; # s p l i t s t r i n g f o r e a c h $uptime ( @uptimes ) # f o r each up time { i f ( $uptime == " UP " ) { # header # do n o t h i n g } e l s i f ( $uptime =~ m/ ( 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 ) / ) { # s a v e up_time i n l o c a l t i m e _ l i n e a r r a y $timeline_up_temp [$# timeline_up_temp + 1 ] = $uptime ; # save event i n event handler $event_hash { $ s r c } { $ d s t } { " up " } { $uptime } { "num ev ent s " } + + ; $event_hash { $ s r c } { $ d s t } { " up " } { $uptime } { $event_hash { $ s r c } { $ d s t } { " up " } { $uptime } { "num ev ent s " } } =$path ; } else { d i e ( " import_data : uptime p a r s e r : unknown $uptime " ) ; } } # save t i m e l i n e $ t i m e l i n e _ u p [ $ s r c ] [ $ d s t ] = [ s o r t ( number_sort @timeline_up_temp ) ] ; # p r o c e s s down time e v e n t s # # # t e m p o r a l a r r a y t o c o n s t r u c t time l i n e my @timeline_down_temp = ( ) ; # c o n t a i n e r s t o work with up and down t i m e s my @downtimes = (); my $downtime = 0; # load t i m e l i n e i f ( $timeline_down [ $ s r c ] [ $ d s t ] == " " ) {# f i r s t path > new @timeline_down_temp = ( ) ; } else {# l o a d o l d time l i n e @timeline_down_temp = @{ $timeline_down [ $ s r c ] [ $ d s t ] } ; } @downtimes = s p l i t ( / / , $down ) ; f o r e a c h $downtime ( @downtimes ) # f o r each down time { i f ( $downtime == "DOWN" ) { #header

161

A.3. Perl

# do n o t h i n g } e l s i f ( $downtime =~ m/ ( 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 ) / ) { # s a v e down_time i n l o c a l t i m e _ l i n e a r r a y $timeline_down_temp [$# timeline_down_temp + 1 ] = $downtime ; # save event i n event handler $event_hash { $ s r c } { $ d s t } { " down " } { $downtime } { "num ev ent s " } + + ; $event_hash { $ s r c } { $ d s t } { " down " } { $downtime } { $event_hash { $ s r c } { $ d s t } { " down " } { $downtime } { "num ev ent s " } } = $path ; } else { d i e ( " import_data : downtime p a r s e r : unknown $downtime " ) ; } } # save t i m e l i n e $timeline_down [ $ s r c ] [ $ d s t ] = [ s o r t ( number_sort @timeline_down_temp ) ] ; } else { d i e " RT : e r r o r . . . } } e l s i f ( $elements [ 0 ] =~ "#RTHSRC " ) { # Header S o u r c e t a b l e } e l s i f ( $elements [ 0 ] =~ "#RTSRC " ) { # rtable src # i n f o r m a t i o n o f t h e r o u t i n g t a b l e o f t h e s o u r c e o f t h e data c o n n e c t i o n # interface definition my $ s r c = $elements [ 1 ] ; my $ d s t = $elements [ 2 ] ; my $min_hop = $elements [ 3 ] ; my $ p at h_ num b er _ at _ t _ s t r i ng = $elements [ 4 ] ; my $ t i m e l i n e _ s t r i n g = $elements [ 5 ] ; i f ( $DEBUG == 1 ) { # parse check print ( " src : $src \ t " ) ; p r i n t ( " d es t : $ d s t \ t " ) ; p r i n t ( " min hop : $min_hop \ t " ) ; p r i n t ( " path : $ p at h_ num b er _ at _ t _ s t r i ng \ t " ) ; print ( " timeline : $timeline_string\ t " ) ; p r i n t ( " \n " ) ; } i f ( $min_hop =~ m/ ( 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 ) / ) {# c h e c k t h a t t h e l i n e c o r r e s p o n d s t o a meaningful d a t a s h e e t # number o f a c t i v e p a t h s # # # parse s t r i n g s my @paths_num_at_t_array my @ t i m e l i n e _ a r r a y = s p l i t ( / / , $ p at h_ num b er _ at _ t _ s t r i ng ) ; = s p l i t (/ / , $ t i m e l i n e _ s t r i n g ) ; $line \n " ;

#c h e c k i f both a r r a y r e a l l y have t h e same l e n g t h i f ( s c a l a r ( @paths_num_at_t_array ) ! = s c a l a r ( @ t i m e l i n e _ a r r a y ) )

162

A.3. Perl

{#have not t h e same l e n g t h d i e ( " RTSRC : TimeS t r i n g has not the same l eng t h as " . " Number o f paths S t r i n g !!> e r r o r \ n " ) ; } # f i r s t element i s o n l y d e s c r i p t i o n $ p at h_ t i m e_ s r c { $ s r c } { $ d s t } { "num s l o t s " } = ( s c a l a r ( @ t i m e l i n e _ a r r a y ) 1 ) ; #copy v a l u e s i n s t a t i s t i c c o n t a i n e r ( s t a r t by s l o t z e r o ) # s t a r t by one > f i r s t element o n l y d e s c r i p t i o n f o r (my $ i i = 1 ; $ i i < s c a l a r ( @paths_num_at_t_array ) ; $ i i ++) { $ p at h_ t i m e_ s r c { $ s r c } { $ d s t } { $ i i 1 } { "num paths " } = $paths_num_ at_t_ array [ $ i i ] ; $ p at h_ t i m e_ s r c { $ s r c } { $ d s t } { $ i i 1 } { " time " } = $timeline_array [ $ i i ] ; } # min hop # $ p at h_ t i m e_ s r c { $ s r c } { $ d s t } { " s h o r t e s t path " } = $min_hop ; } } else { # p r i n t ( " no match " , $ e l e m e n t s [ 0 ] } } # n o r m a l i s a t i o n ( dropped p a c k e t ) f o r (my $ i i = 0 ; $ i i < $ n o d e _ t o t a l ; $ i i ++) { # Add + 1 t o be s u r e t h a t we have no d i v i s i o n by z e r o e v e n t . . . $ d r o p p ed _ d p acke t s _ v _ t o t _ s e n t [ $ i i ] = $dropped_packet_data_node [ $ i i ] / ( 1 + $ s e n t _ p a c k e t _ d a t a _ t o t a l ) ; $ d r o p p ed _ d p acket s _ v _ r ecei v ed _ no d e [ $ i i ] = $dropped_packet_data_node [ $ i i ] / ( 1 + $ r ecei v ed _ p a c k et _ d a t a _ n o d e [ $ i i ] + $forwarded_packet_d ata_ node [ $ i i ] ) ; } # close f i l e c l o s e ( SI M_ F I L E ) o r d i e " Couldn t c l o s e $ s i m _ f i l e \ n " ; } sub number_sort { # h e l p e r f u n c t i o n t o s o r t time e v e n t s i f ( $a < $b ) { r e t u r n 1; } e l s i f ( $a == $b ) { return 0; } else { return 1 ; } } # # CALCULATIONS ## sub c a l c u l a t e _ s t a t _ r t _ s _ t { # c a l c u l a t i o n s based on t h e i n f o r m a t i o n out o f t h e r o u t i n g t a b l e s p a c e time # # # # c a l c u l a t e fo r $connection : 1 . f i n d out which p a t h s were a c t i v e a t which time 2 . c a l c u l a t e t h e number o f found p a t h s based on t h e r o u t i n g t a b l e i n f o r m a t i o n 3 . c a l c u l a t e t h e a v e r a ge number o f found p a t h s based on t h e r o u t i n g t a b l e i n f o ,"\n " ) ;

# Variable Declaration .

163

A.3. Perl

#c o n s t a n t my $ I N F I N I T Y #argument my $ co nnect i o n #l oc a l varables my $ s r c my $ d s t my $ p a t h _ t o t a l

= 9999999;

= s h i f t (@_ ) ;

= $ s r c _ d e s t { $ co nnect i o n } { " s r c " } ; = $ s r c _ d e s t { $ co nnect i o n } { " d s t " } ; = $ s r c _ d e s t _ p a t h { $ s r c } { $ d s t } { "num paths " } ;

# Timeline fo r t h i s connection my @timeline_up_ = @{ $ t i m e l i n e _ u p [ $ s r c ] [ $ d s t ] } ; my @timeline_down_ = @{ $timeline_down [ $ s r c ] [ $ d s t ] } ; # p o i n t e r t o t h e a c t i v e element o f t h e t i m e l i n e my $ t i m e l i n e _ u p _ n e x t _ p o i n t e r = 0; my $ t i m el i ne_ d o w n_ nex t _ p o i nt e r = 0 ; my $time my $ t i m e _ l a s t # Handle z e r o p o i n t e r : i f ( s c a l a r ( @timeline_up_ ) == 0) { # no up e v e n t p r i n t f ( " no up event . . . \ n " ) ; $ t i m el i ne_ up _ [ 0 ] = $ I N F I N I T Y ; } i f ( s c a l a r ( @timeline_down_ ) == 0) { # no down e v e n t p r i n t f ( " no down event . . . \ n " ) ; $timeline_down_ [ 0 ] = $ I N F I N I T Y ; } my $time_up_next my $time_down_next = $ t i m el i ne_ up _ [ 0 ] ; = $timeline_down_ [ 0 ] ; = 0; = 0;

# v a r i a b l e to save s t a r t of the connection #my $ t i m e _ c o n n e c t i o n _ s t a r t = $ I N F I N I T Y ; # v a r i a b l e t o s a v e end o f t h e c o n n e c t i o n #my $ t i m e _ c o n n e c t i o n _ e n d = 0; # r e g i s t e r t o s a v e t h e s t a t e o f t h e p a t h s d u r i n g t h e time $time my @ p a t h _ a c t i v e _ r e g i s t e r = ( ) ; # p a t h _ a c t i v e _ r e g i s t e r [# path_hash ] = $time_up my $path_active_number = 0 ; #number o f a c t i v e p a t h s a t time $time

my $ ev ent _ t y p e

= "";

# I n i t i a l i s a t i o n of the Values # ( F i r s t Time S l o t ) # # i f ( $time_up_next <= $time_down_next ) # f i r s t e v e n t must be a UPEVENT { $time_last = 0; $time = $ t i m el i ne_ up _ [ 0 ] ; # n e x t up time w hi l e ( $ t i m e l i n e _ u p _ n e x t _ p o i n t e r < s c a l a r ( @timeline_up_ )

164

A.3. Perl

&& $ t i m el i ne_ up _ [ $ t i m e l i n e _ u p _ n e x t _ p o i n t e r ] == $time_up_next ) { $timeline_up_next_pointer ++; } $time_up_next = $ t i m el i ne_ up _ [ $ t i m e l i n e _ u p _ n e x t _ p o i n t e r ] ; $time_down_next = $timeline_down_ [ $ t i m el i ne_ d o w n_ nex t _ p o i nt er ] ; $ t i m el i ne_ d o w n_ nex t _ p o i nt er + + ; # s a v e f i r s t time $ p at h_ t i m e_ s _ t { $ s r c } { $ d s t } { "num s l o t s " } = 1 ; $ p at h_ t i m e_ s _ t { $ s r c } { $ d s t } { 1 } { " time " } = $time ; # next event type $ ev ent _ t y p e # number o f p a t h s $path_active_number @path_active_register } else { p r i n t ( " up_next : $time_up_next down_next : $time_down_next \ n " ) ; d i e ( " CALC RT_S_T : f i r s t element i n t i m e l i n e was not a up event ! ! " ) ; }

= " up " ;

= 0; = ();

# Wake through t h e s i m u l a t i o n # u n t i l t h e end o f t h e s i m u l a t i o n # # w hi l e ( $time < $ I N F I N I T Y ) { # update data f o r $time # # i f ( $ ev ent _ t y p e =~ " up " ) { #UP f o r ( my $ i i = 1 ; $ i i <= $event_hash { $ s r c } { $ d s t } { " up " } { $time } { "num ev ent s " } ; $ i i ++) { # update a c t i v e path r e g i s t e r my $ l o o p _ p at h = $event_hash { $ s r c } { $ d s t } { " up " } { $time } { $ i i } ; my $loop_path_hash = $ s r c _ d e s t _ p a t h { $ s r c } { $ d s t } { $ l o o p _ p at h } ; $ p a t h _ a c t i v e _ r e g i s t e r [ $loop_path_hash ] = $time ; # s e t path as a c t i v e } } e l s i f ( $ ev ent _ t y p e =~ " down " ) { #DOWN f o r ( my $ i i = 1 ; $ i i <= $event_hash { $ s r c } { $ d s t } { " down " } { $time } { "num ev ent s " } ; $ i i ++) { # update a c t i v e path r e g i s t e r my $ l o o p _ p at h = $event_hash { $ s r c } { $ d s t } { " down " } { $time } { $ i i } ; my $loop_path_hash = $ s r c _ d e s t _ p a t h { $ s r c } { $ d s t } { $ l o o p _ p at h } ; $ p a t h _ a c t i v e _ r e g i s t e r [ $loop_path_hash ] = 0 ; # s e t path as not working } } else { d i e ( " CALC RT_S_T : unknown event \ n " ) ; }

# c a l c u l a t e t h e number o f a c t i v e p a t h s

165

A.3. Perl

$path_active_number = 0 ; f o r (my $ i i = 1 ; $ i i <= $ p a t h _ t o t a l ; $ i i ++) { i f ( $ p a t h _ a c t i v e _ r e g i s t e r [ $ i i ] > 0) { $path_active_numb er + + ; } } # s a v e data my $ l o o p _ s l o t = $ p at h_ t i m e_ s _ t { $ s r c } { $ d s t } { "num s l o t s " } ; $ p at h_ t i m e_ s _ t { $ s r c } { $ d s t } { $ l o o p _ s l o t } { "num a c t i v e paths " } = $path_active_numb er ; $path_time_s_t_active_paths [ $s r c ] [ $dst ] [ $l o o p _ s l o t ] = [ @p at h_ act i ve_ r eg i s t er ] ;

# update time # # my $ d e c i s i o n = " " ; # d e c i s i o n next event : # > S e t d e c i s i o n t o UP /DOWN i f ( $time_up_next < $time_down_next ) { $ d e c i s i o n = " UP " ; } e l s i f ( $time_up_next > $time_down_next ) { $ d e c i s i o n = "DOWN" ; } e l s i f ( $time_up_next == $ I N F I N I T Y && $time_down_next == $ I N F I N I T Y ) { # end o f s i m u l a t i o n , d e c i s i o n i s not i r r e l e v a n t $ d e c i s i o n = "DOWN" ; } e l s i f ( $time_up_next == $time_down_next ) { # Problem : Time d i s c r e t i s a t i o n was too s m a l l . # E v e n t s a r e p r o b a b l y c o l l e c t e d i n one time s l o t . . . # # S o l u t i o n : c r ea t e independent events ! ! # f o r each up e v e n t > ++ # f o r each down e v e n t > my @action = ( ) ; f o r ( my $ i i = 1 ; $ i i <= $event_hash { $ s r c } { $ d s t } { " up " } { $time_up_next } { "num ev ent s " } ; { my $ l o o p _ p at h = $event_hash { $ s r c } { $ d s t } { " up " } { $time_up_next } { $ i i } ; my $loop_path_hash = $ s r c _ d e s t _ p a t h { $ s r c } { $ d s t } { $ l o o p _ p at h } ; $ a c t i o n [ $loop_path_hash ] + + ; } f o r ( my $ i i <= { my my $ii = 1; $event_hash { $ s r c } { $ d s t } { " down " } { $time_down_next } { "num ev ent s " } ;

$ i i ++)

$ i i ++)

$ l o o p _ p at h = $event_hash { $ s r c } { $ d s t } { " down " } { $time_down_next } { $ i i } ; $loop_path_hash = $ s r c _ d e s t _ p a t h { $ s r c } { $ d s t } { $ l o o p _ p at h } ;

$ a c t i o n [ $loop_path_hash ]; } # # # # overwrite > i f 1 > i f 0 > i f 1 events > UP > n o t h i n g > DOWN

166

A.3. Perl

# > e l s e > ERROR ! ! ! ! $event_hash { $ s r c } { $ d s t } { " up " } { $time_up_next } { "num ev ent s " } = 0 ; $event_hash { $ s r c } { $ d s t } { " down " } { $time_down_next } { "num ev ent s " } = 0 ; f o r ( my $ i i = 1 ; $ i i <= $ p a t h _ t o t a l ; $ i i ++) { # overwrite events my $ l o o p _ p at h = $ s r c _ d e s t _ p a t h { $ s r c } { $ d s t } { $ i i } ; i f ( $action [ $ i i ]==1) {# UP EVENT $event_hash { $ s r c } { $ d s t } { " up " } { $time_up_next } { "num ev ent s " } + + ; $event_hash { $ s r c } { $ d s t } { " up " } { $time_up_next } { $event_hash { $ s r c } { $ d s t } { " up " } { $time_up_next } { "num ev ent s " } } = $ l o o p _ p at h ; } e l s i f ( $ a c t i o n [ $ i i ] == 1) {# DOWN EVENT $event_hash { $ s r c } { $ d s t } { " down " } { $time_down_next } { "num ev ent s " } + + ; $event_hash { $ s r c } { $ d s t } { " down " } { $time_down_next } { $event_hash { $ s r c } { $ d s t } { " down " } { $time_down_next } { "num ev ent s " } } = $ l o o p _ p at h ; } e l s i f ( $ a c t i o n [ $ i i ] == 0) {# no a c t i o n } else {# e r r o r ! d i e ( " to many ev ent s f o r t h i s path . . . } } $ d e c i s i o n = " UP" ; } $ t i m e _ l a s t = $time ; # update time a c c o r d i n g t o $ d e c i s i o n # # i f ( $ d e c i s i o n =~ " UP" ) { #Next e v e n t i s a UP e v e n t $time = $time_up_next ; $ ev ent _ t y p e = " up " ; # c a l c u l a t e n e x t up time w hi l e ( $ t i m e l i n e _ u p _ n e x t _ p o i n t e r < s c a l a r ( @timeline_up_ ) && $ t i m el i ne_ u p _ [ $ t i m e l i n e _ u p _ n e x t _ p o i n t e r ] == $time_up_next ) { $timeline_up_next_pointer ++; } i f ( $ t i m e l i n e _ u p _ n e x t _ p o i n t e r < s c a l a r ( @timeline_up_ ) ) { $time_up_next = $ t i m el i ne_ u p _ [ $ t i m e l i n e _ u p _ n e x t _ p o i n t e r ] ; } else { $time_up_next = $INFINITY ; } } e l s i f ( $ d e c i s i o n =~ "DOWN" ) { # Next e v e n t i s a DOWN e v e n t

: $action [ $ i i ] \ n" )

167

A.3. Perl

$time = $time_down_next ; $ ev ent _ t y p e = " down " ; # n e x t down time w hi l e ( $ t i m el i ne_ d o w n_ nex t _ p o i nt er < s c a l a r ( @timeline_down_ ) && $timeline_down_ [ $ t i m el i ne_ d o w n_ nex t _ p o i nt er ] == $time_down_next ) { $ t i m el i ne_ d o w n_ nex t _ p o i nt er + + ; } i f ( $ t i m el i ne_ d o w n_ nex t _ p o i nt er < s c a l a r ( @timeline_down_ ) ) { $time_down_next = $timeline_down_ [ $ t i m el i ne_ d o w n_ nex t _ p o i nt er ] ; } else { $time_down_next = $ I N F I N I T Y ; } } else { die ( " Decision : $decision " ) ; } $ p at h_ t i m e_ s _ t { $ s r c } { $ d s t } { "num s l o t s " } + + ; my $ l o o p _ t i m e _ s l o t = $ p at h_ t i m e_ s _ t { $ s r c } { $ d s t } { "num s l o t s " } ; $ p at h_ t i m e_ s _ t { $ s r c } { $ d s t } { $ l o o p _ t i m e _ s l o t } { " time " } = $time ; } #w h i l e end ( END OF SIMULATION DATA ) } sub c a l c u l a t e _ s t a t _ r t _ s r c { # c a l c u l a t e s t a t i s t i c s based on t h e r t a b l e _ s r c ( as s r c s e e s i t ) # 1 . number o f p a t h s on a v e r a ge # 2 . number o f found p a t h s f o r one r o u t e r e q u e s t # a v e r a g e s o v e r a f i x timewindows : # # l e f t window r i g h t window # Y Y # # ______ | _ _ _ _ _ _ _ _ _ _ _ _ # # 180 l a s t data p a c k e t s e n t # my $ co nnect i o n my $ I N F I N I T Y my $ s r c my $ d s t my $ s h o r t e s t _ p a t h my $ t i m e _ l a s t my $time my $number_of_paths = s h i f t ( @_ ) ; = 9999999; = $ s r c _ d e s t { $ co nnect i o n } { " s r c " } ; = $ s r c _ d e s t { $ co nnect i o n } { " d s t " } ; = $ p at h_ t i m e_ s r c { $ s r c } { $ d s t } { " s h o r t e s t path " } ; = $ p at h_ t i m e_ s r c { $ s r c } { $ d s t } { 0 } { " time " } ; = $ p at h_ t i m e_ s r c { $ s r c } { $ d s t } { 1 } { " time " } ; = $ p at h_ t i m e_ s r c { $ s r c } { $ d s t } { 0 } { "num paths " } ;

# A v e r a ge 180 S i m u l a t i o n End ( l a s t data p a c k e t ) my $number_of_paths_time_180_avg = 0; my $number_of_path_time_180_max = 0; my $window_180_start my $window_180_stop = 180; = $ s i m ul at i o n_ end ;

# R o u t i n g P r o t o c o l P e r f o r m a n c e ( T r y t o remove I n t e r f a c e C a l l b a c k e f f e c t )

168

A.3. Perl

# I d e a : f i n d t h e number o f p a t h s t h a t can be found by one r o u t e r e q u e s t # I m p l e m e n t a t io n : Route r e q u e s t > S t a r t s a f t e r a l o n g e r Z e r o P e r i o d # ( no p a t h s i n t h e r o u t i n g t a b l e ) # # P e r f o r m a n c e = Max P a t h s between t o Z e r o s P e r i o d s # Problem : D e f i n e l o n g e r Z e r o P e r i o d ! ! # s h o r t z e r o e v e n t s o c c u r s due t o r o u t i n g t a b l e u p d a t e s . . . # d e f i n e Z e r o P e r i o d e >> r o u t i n g update # i f a r o u t e r e q u e s t can t f i n d a r o u t e > l o n g e r z e r o p e r i o d . . # > t h i s i s not c a p t u r e d with t h i s t e c h n i q u e . . . my $ZERO_PERIOD_DURATION my $locale_maximum = 0.01; = 0; #[ s ]

# # F i r s t loop over the s i m u l a ti on # # c a l c number o f found p a t h s on a v e r a ge # c a l c number o f found p a t h s f o r one r o u t e r e q u e s t f o r (my $ i i = 1 ; $ i i < $ p at h_ t i m e_ s r c { $ s r c } { $ d s t } { "num s l o t s " } ; { # Routing P r o t o c o l Performance # # i f ( $time_last > 180) { # f i n d l o c a l maximum i f ( $number_of_paths > $locale_maximum ) { $locale_maximum = $number_of_paths ; } $ i i ++)

#c h e c k i f t h i s i s a Z e r o P e r i o d i f ( ( $time$ t i m e _ l a s t >= $ZERO_PERIOD_DURATION )&& ( $number_of_paths == 0 ) ) { $ r p _ p er f o r m ace [ $ s h o r t e s t _ p a t h ] [ $locale_maximum ] + + ; $locale_maximum = 0 ; } } # A v e r a ge 180 # # i f ( $time > $window_180_start && $ t i m e _ l a s t < $window_180_stop ) { # c h e c k window my $ l e f t _ s i d e = 0 ; my $ r i g h t _ s i d e = 0 ; i f ( $window_180_start > $ t i m e _ l a s t ) { $ l e f t _ s i d e = $window_180_start ; } else { $left _s ide = $time_last ; } i f ( $window_180_stop < $time ) { $ r i g h t _ s i d e = $window_180_stop ; } else { $ r i g h t _ s i d e = $time ;

169

A.3. Perl

} # Time A v e r a ge # # $number_of_paths_time_180_avg += ( $ r i g h t _ s i d e $ l e f t _ s i d e ) $number_of_paths ; i f (0) { p r i n t f ( "DEBUG c a l c s r c : SRC %s DEST %s \ n TIME %s LAST TIME %s " . " dT %s NUM Path %s LEFT %s RIGHT%s AVG_NOT_NORM %s \ n " , $ s r c , $dst , $time , $ t i m e _ l a s t , ( $time $ t i m e _ l a s t ) , $number_of_paths , $ l e f t _ s i d e , $ r i g h t _ s i d e , $number_of_paths_time_180_avg ) ; my $menu = <STDIN > ; chomp $menu ; } # Max P a t h s # # i f ( $number_of_paths > $number_of_path_time_180_max ) { $number_of_path_time_180_max = $number_of_paths ; } }

#update data ( $time ) $number_of_paths = $ p at h_ t i m e_ s r c { $ s r c } { $ d s t } { $ i i } { "num paths " } ; # n e x t time $time_last $time } # EXCEPTION HANDLE OF AVERAGE CALCULATION # # Problem # 1 : i f no e v e n t o c c u r s d u r i n g t h e window s i z e > a d j u s t l e f t and r i g h t window s i d e # 2 : i f t h e r e i s no e v e n t o u t s i d e t h e windows > a d j u s t r i g h t window s i d e i f ( $ t i m e _ l a s t < $window_180_stop ) { my $ l e f t _ s i d e ; my $ r i g h t _ s i d e ; $ r i g h t _ s i d e = $window_180_stop ; i f ( $ t i m e _ l a s t < $window_180_start ) { $ l e f t _ s i d e = $window_180_start ; } else { $left _s ide = $time_last ; } $number_of_paths_time_180_avg += ( $ r i g h t _ s i d e $ l e f t _ s i d e ) $number_of_paths ; i f (0) { p r i n t f ( "DEBUG c a l c s r c : SRC %s DEST %s \ n " . " TIME %s LAST TIME %s dT %s NUM Path %s LEFT %s RIGHT%s AVG_NOT_NORM %s \ n " , $ s r c , $dst , $time , $ t i m e _ l a s t , ( $time $ t i m e _ l a s t ) , $number_of_paths , $ l e f t _ s i d e , $ r i g h t _ s i d e , $number_of_paths_time_180_avg ) ; } }

= $time ; = $ p at h_ t i m e_ s r c { $ s r c } { $ d s t } { $ i i + 1 } { " time " } ;

170

A.3. Perl

# N o r m a l i s a t i o n ( time a v e r a ge ) ( p l u s 1 ==> a v o i d d i v i s i o n by z e r o ) $number_of_paths_time_180_avg = $number_of_paths_time_180_avg / ( $window_180_stop $window_180_start + 1 ) ; $ p at h_ t i m e_ s r c { $ s r c } { $ d s t } { " 180 avg " } # max path $ p at h_ t i m e_ s r c { $ s r c } { $ d s t } { " 180 max " } = $number_of_paths_time_180_avg ;

= $number_of_path_time_180_max ;

p r i n t f ( " \ n \ nCALC_SRC : SRC %s DEST %s TIME %s \ n " , $ s r c , $dst , $time ) ; p r i n t f ( " CALC_SRC 180 mean : %s max : %s l e f t %s r i g h t %s time : %s l a s t time : %s \ n \ n " , $ p at h_ t i m e_ s r c { $ s r c } { $ d s t } { " 180 avg " } , $ p at h_ t i m e_ s r c { $ s r c } { $ d s t } { " 180 max " } , $window_180_start , $window_180_stop , $time , $ t i m e _ l a s t ) ; } sub c a l c _ s t a t _ s h o r t e s t { # c a l c u l a t e a l l s t a t i s t i c s i n r e s p e c t on s h o r t e s t path calc_stat_shortest_connection ( ) ; calc_stat_shortest_180_time ( ) ; calc_stat_shortest_180_max ( ) ; calc_stat_shortest_180_rp_p ( ) ; } sub c a l c _ s t a t _ s h o r t e s t _ c o n n e c t i o n { # c a l c u l a t e t h e d i s t r i b u t i o n o f s h o r t e s t path l e n g t h s i n t h e s i m u l a t i o n # f i n d t h e l o n g e s t s h o r t e s t path i n t h e s i m u l a t i o n my $number_of_connections = $ s r c _ d e s t { "num con " } ; my @connections = ( ) ; my $shortest_path_max = 0 ; # loop v a r i a b l e s my $ s r c = 0; my $ d s t = 0; my $ s h o r t e s t _ p a t h = 0 ;

f o r (my $ i i = 1 ; $ i i { # interface $src $dst $shortest_path

<= $number_of_connections ; $ i i ++) #l o o p o v e r con

= $src_dest { $ i i } { " src " } ; = $s r c_des t { $ i i } { " dst " } ; = $ p at h_ t i m e_ s r c { $ s r c } { $ d s t } { " s h o r t e s t path " } ;

# d i s t r i b u t i o n of the connections $ co nnect i o n s [ $ s h o r t e s t _ p a t h ] + + ; # l o n g e s t s h o r t e s t path i f ( $shortest_path_max < $ s h o r t e s t _ p a t h ) { $shortest_path_max = $ s h o r t e s t _ p a t h ; } } # s a v e data f o r (my $ i i = 1 ; $ i i <= $shortest_path_max ; $ i i ++) # l o o p o v e r s h o r t e s t { i f ( $ co nnect i o ns [ $ i i ] == " " ) # problem by c o n v e r t i n g " " t o i n t { $ p a t h _ s h o r t e s t { $ i i } { "num con " } = 0 ; } else

171

A.3. Perl

{ $ p a t h _ s h o r t e s t { $ i i } { "num con " } = $ co nnect i o n s [ $ i i ] ; } } $ p a t h _ s h o r t e s t { " s h o r t e s t path max " } = $shortest_path_max ; #DEBUG OUTPUT i f ( $DEBUG == 1 ) { my $connection_sum = 0 ; p r i n t f ( " \ n \ n c a l c _ s t a t _ c o n n e c t i o n \n " ) ; p r i n t f ( " Connection S t a t i s t i c \ n " ) ; p r i n t f ( "max s h o r t e s t path : %i \ n " , $ p a t h _ s h o r t e s t { " s h o r t e s t path max " } ) ; f o r (my $ i i = 1 ; $ i i <= $ p a t h _ s h o r t e s t { " s h o r t e s t path max " } ; $ i i ++) { p r i n t f ( " S h o r t e s t path : %2. i number o f co nnect i o ns : %4. i \ n " , $ i i , $ p a t h _ s h o r t e s t { $ i i } { "num con " } ) ; $connection_sum += $ p a t h _ s h o r t e s t { $ i i } { "num con " } ; } #c h e c k i f some c o n n e c t i o n s were l o s t i n s p a c e . . . i f ( $connection_sum ! = $ s r c _ d e s t { "num con " } ) { d i e " c a l c _ s t a t _ c o n n e c t i o n : D i f f e r e n c e i n t o t a l number o f co nnect i o n } else { p r i n t f ( " Number o f C o nnect i o ns : %i \ n " , $ s r c _ d e s t { "num con " } ) ; } } } sub c a l c _ s t a t _ s h o r t e s t _ 1 8 0 _ t i m e { # TIME AVERAGE # C a l c u l a t e t h e number o f a c t i v e p a t h s i n time a v e r a ge # S t a r t time = 180 # End time = time when t h e l a s t data p a c k e t was s e n t # INPUT : # OUTPUT : # $ p a t h _ s h o r t e s t { $ i i } { " 1 8 0 time avg " } = $avg ; # $ p a t h _ s h o r t e s t { $ i i } { " 1 8 0 time v a r " } = $ v a r ;

... ";

# c a l c u l a t e s t a t i s t i c s with r e s p e c t t o t h e s h o r t e s t path : my $number_of_connections my $shortest_path_max = $ s r c _ d e s t { "num con " } ; = $ p a t h _ s h o r t e s t { " s h o r t e s t path max " } ;

# interface my $ s r c_ s am p l e = 0; my $dst_sample = 0; my $avg_sample = 0; my $ s ho r t es t _ p at h_ s am p l e = 0 ; # l o c a l data c o n t a i n e r my @avg = ( ) ; # a v e r a ge my @var = ( ) ; # variance my @samples = ( ) ; # number o f c o n n e c t i o n s =~ samples # AVERAGE

172

A.3. Perl

# # f o r (my $ i i = 1 ; $ i i <= $number_of_connections ; $ i i ++) # l o o p o v e r con { # interface $ s r c_ s am p l e = $ s r c _ d e s t { $ i i } { " s r c " } ; $dst_sample = $ s r c _ d e s t { $ i i } { " d s t " } ; $avg_sample = $ p at h_ t i m e_ s r c { $ s r c_ s am p l e } { $dst_sample } { " 180 avg " } ; $ s ho r t es t _ p at h_ s am p l e = $ p at h_ t i m e_ s r c { $ s r c_ s am p l e } { $dst_sample } { " s h o r t e s t path " } ; # calc $avg [ $ s ho r t es t _ p at h_ s am p l e ] += $avg_sample ; $samples [ $ s ho r t es t _ p at h_ s am p l e ] + + ; } # normalisation f o r (my $ i i = 1 ; $ i i <= $shortest_path_max ; $ i i ++) # l o o p o v e r s h o r t e s t { i f ( $samples [ $ i i ] > 0) # d i v i s i o n by z e r o { $avg [ $ i i ] = $avg [ $ i i ] / $samples [ $ i i ] ; } else { $avg [ $ i i ] = 0 ; } } # VARIANCE # # f o r (my $ i i = 1 ; $ i i <= $number_of_connections ; $ i i ++) # l o o p o v e r con { # interface $ s r c_ s am p l e = $src_dest { $ i i } { " src " } ; $dst_sample = $s r c_des t { $ i i } { " dst " } ; $avg_sample = $ p at h_ t i m e_ s r c { $ s r c_ s am p l e } { $dst_sample } { " 180 avg " } ; $ s ho r t es t _ p at h_ s am p l e = $ p at h_ t i m e_ s r c { $ s r c_ s am p l e } { $dst_sample } { " s h o r t e s t path " } ; # calc $ v a r [ $ s ho r t es t _ p at h_ s am p l e ] += ( $avg_sample $avg [ $ s ho r t es t _ p at h_ s am p l e ] ) 2 ; } # normalisation f o r (my $ i i = 1 ; $ i i <= $shortest_path_max ; $ i i ++) # l o o p o v e r s h o r t e s t { i f ( $samples [ $ i i ] > 0) # d i v i s i o n by z e r o { $ v a r [ $ i i ] = $ v a r [ $ i i ] / $samples [ $ i i ] ; } else { $var [ $ i i ] = 0; } } # SAVE DATA # # f o r (my $ i i = 1 ; $ i i <= $shortest_path_max ; $ i i ++) # l o o p s h o r t e s t path { $ p a t h _ s h o r t e s t { $ i i } { " 180 time avg " } = $avg [ $ i i ] ; $ p a t h _ s h o r t e s t { $ i i } { " 180 time v a r " } = $ v a r [ $ i i ] ; }

173

A.3. Perl

# DEBUG OUTPUT i f ( $DEBUG == 1 ) { p r i n t f ( " \ n \ n c a l c _ s t a t _ 1 8 0 _ t i m e \n " ) ; p r i n t f ( " A c t i v e paths o v er time o v er a l l co nnect i o ns \ n " ) ; f o r (my $ i i = 1 ; $ i i <= $shortest_path_max ; $ i i ++) { p r i n t f ( " S h o r t e s t path : %2. i avg : %2.4 f v a r : %2.4 f \ n " , $ i i , $ p a t h _ s h o r t e s t { $ i i } { " 180 time avg " } , $ p a t h _ s h o r t e s t { $ i i } { " 180 time v a r " } ) ; } } } sub c a l c _ s t a t _ s h o r t e s t _ 1 8 0 _ m a x { # MAXIMUM OVER TIME # C a l c u l a t e t h e number o f maximum a c t i v e p a t h s i n time a v e r a ge o v e r a l l c o n n e c t i o n s # OUTPUT : # $ p a t h _ s h o r t e s t { $ i i } { " 1 8 0 max avg " } = $avg ; # $ p a t h _ s h o r t e s t { $ i i } { " 1 8 0 max v a r " } = $ v a r ;

# c a l c u l a t e s t a t i s t i c s with r e s p e c t t o t h e s h o r t e s t path : my $number_of_connections my $shortest_path_max # interface my $ s r c_ s am p l e = 0; my $dst_sample = 0; my $max_sample = 0; my $ s ho r t es t _ p at h_ s am p l e = 0 ; # l o c a l data c o n t a i n e r my @avg = ( ) ; # a v e r a ge my @var = ( ) ; # variance my @samples = ( ) ; # number o f c o n n e c t i o n s =~ samples # AVERAGE # # f o r ( my $ i i = 1 ; $ i i <= $number_of_connections ; $ i i ++) # l o o p o v e r c o n n e c t i o n s { # interface $ s r c_ s am p l e = $src_dest { $ i i } { " src " } ; $dst_sample = $s r c_des t { $ i i } { " dst " } ; $max_sample = $ p at h_ t i m e_ s r c { $ s r c_ s am p l e } { $dst_sample } { " 180 max " } ; $ s ho r t es t _ p at h_ s am p l e = $ p at h_ t i m e_ s r c { $ s r c_ s am p l e } { $dst_sample } { " s h o r t e s t path " } ; # calc $avg [ $ s ho r t es t _ p at h_ s am p l e ] += $max_sample ; $samples [ $ s ho r t es t _ p at h_ s am p l e ] + + ; } # normalisation f o r ( my $ i i = 1 ; $ i i <= $shortest_path_max ; $ i i ++) # l o o p o v e r s h o r t e s t path { i f ( $samples [ $ i i ] > 0) # d i v i s i o n by z e r o { $avg [ $ i i ] = $avg [ $ i i ] / $samples [ $ i i ] ; } else { $avg [ $ i i ] = 0 ; = $ s r c _ d e s t { "num con " } ; = $ p a t h _ s h o r t e s t { " s h o r t e s t path max " } ;

174

A.3. Perl

} } # VARIANCE # # f o r (my $ i i = 1 ; $ i i <= $number_of_connections ; $ i i ++) # l o o p o v e r con { # interface $ s r c_ s am p l e = $src_dest { $ i i } { " src " } ; $dst_sample = $s r c_des t { $ i i } { " dst " } ; $max_sample = $ p at h_ t i m e_ s r c { $ s r c_ s am p l e } { $dst_sample } { " 180 max " } ; $ s ho r t es t _ p at h_ s am p l e = $ p at h_ t i m e_ s r c { $ s r c_ s am p l e } { $dst_sample } { " s h o r t e s t path " } ; # calc $ v a r [ $ s ho r t es t _ p at h_ s am p l e ] += ( $max_sample $avg [ $ s ho r t es t _ p at h_ s am p l e ] ) 2 ; } # normalisation f o r (my $ i i = 1 ; $ i i <= $shortest_path_max ; $ i i ++) # l o o p o v e r s h o r t e s t path { i f ( $samples [ $ i i ] > 0) # d i v i s i o n by z e r o { $ v a r [ $ i i ] = $ v a r [ $ i i ] / $samples [ $ i i ] ; } else { $var [ $ i i ] = 0; } } # SAVE DATA # # f o r (my $ i i = 1 ; $ i i <= $shortest_path_max ; $ i i ++) # l o o p s h o r t e s t path { $ p a t h _ s h o r t e s t { $ i i } { " 180 max avg " } = $avg [ $ i i ] ; $ p a t h _ s h o r t e s t { $ i i } { " 180 max v a r " } = $ v a r [ $ i i ] ; } # DEBUG OUTPUT i f ( $DEBUG == 1 ) { p r i n t f ( " \ n \ n cal c_ s t at _ 1 8 0 _ m ax \n " ) ; p r i n t f ( "Maximum A c t i v e paths o v er time o v er a l l co nnect i o ns \ n " ) ; f o r ( my $ i i = 1 ; $ i i <= $shortest_path_max ; $ i i ++) { p r i n t f ( " S h o r t e s t path : %2. i avg : %2.4 f v a r : %2.4 f \ n " , $ii , $ p a t h _ s h o r t e s t { $ i i } { " 180 max avg " } , $ p a t h _ s h o r t e s t { $ i i } { " 180 max v a r " } ) ; } } } sub c a l c _ s t a t _ s h o r t e s t _ 1 8 0 _ r p _ p { # C a l c u l a t e the Performance of the Routing P r o t o c o l # by c a l c u l a t i n g t h e a v e r a ge found p a t h s by one Route R e q u e s t # INPUT : $ r p _ p e r f o r m a n c e a r r a y # OUTPUT : # $ p a t h _ s h o r t e s t {# s h o r t e s t path } { " 1 8 0 rp_p avg " } # $ p a t h _ s h o r t e s t {# s h o r t e s t path } { " 1 8 0 rp_p v a r } # $ p a t h _ s h o r t e s t {# s h o r t e s t path } { " 1 8 0 rp_p samples " }

175

A.3. Perl

#Bound A r r a y # worst case . . . my $LONGEST_SHORTEST_PATH = $ p a t h _ s h o r t e s t { " s h o r t e s t path max " } ; my $MAX_PATHS = 1 0 0 ; f o r ( my { my my my $ i i = 1 ; $ i i <= $LONGEST_SHORTEST_PATH ; $ i i ++) # s h o r t e s t path $avg = 0 ; $var = 0; $ r o u t e _ r e q u e s t _ t o t a l =0;

# a v e r a ge & number o f r e q u e s t s f o r (my $ j j = 1 ; $ j j <= $MAX_PATHS ; $ j j ++) { $avg += $ j j $ r p _ p er f o r m ace [ $ i i ] [ $ j j ] ; $ r o u t e _ r e q u e s t _ t o t a l += $ r p _ p er f o r m ace [ $ i i ] [ $ j j ] ; } i f ( $ r o u t e _ r e q u e s t _ t o t a l > 0) # d i v i s i o n by z e r o { $avg = $avg / $ r o u t e _ r e q u e s t _ t o t a l ; } else { $avg = 0 ; }

# variance f o r (my $ j j = 1 ; $ j j <= $MAX_PATHS ; $ j j ++) { $ v a r += $ r p _ p er f o r m ace [ $ i i ] [ $ j j ] ( ( $ j j $avg ) 2 ) ; } i f ( $ r o u t e _ r e q u e s t _ t o t a l >0) # d i v i s i o n by z e r o { $var = $var / $route_request_total ; } else { $var = 0; } # s a v e data i n s t a t i s t i c c o n t a i n e r $ p a t h _ s h o r t e s t { $ i i } { " 180 rp_p avg " } = $avg ; $ p a t h _ s h o r t e s t { $ i i } { " 180 rp_p v a r " } = $ v a r ; $ p a t h _ s h o r t e s t { $ i i } { " 180 rp_p num r r e q " } = $ r o u t e _ r e q u e s t _ t o t a l ; } #DEBUG OUTPUT i f ( $DEBUG == 1 ) { my $ s a m p l e _ t o t a l = 0 ; p r i n t f ( " \ n \ n c a l c _ s t a t _ 1 8 0 _ r p _ p \n " ) ; p r i n t f ( " Routing P r o t o c o l Performance \ n " ) ; f o r (my $ i i = 0 ; $ i i <= $ p a t h _ s h o r t e s t { " s h o r t e s t path max " } ; $ i i ++) { p r i n t f ( " S h o r t e s t path : %4. i avg : %6.3 f v a r : %6.3 f samples : %4. i \ n " , $ i i , $ p a t h _ s h o r t e s t { $ i i } { " 180 rp_p avg " } , $ p a t h _ s h o r t e s t { $ i i } { " 180 rp_p v a r " } , $ p a t h _ s h o r t e s t { $ i i } { " 180 rp_p num r r e q " } ) ; $ s a m p l e _ t o t a l += $ p a t h _ s h o r t e s t { $ i i } { " 180 rp_p num r r e q " } ; }

176

A.3. Perl

p r i n t f ( " T o t a l number o f samples : %i \ n " , $ s a m p l e _ t o t a l ) ; # show samples # Header p r i n t f ( " \n " ) ; p r i n t f ( " Number o f samples ( s h o r t e s t path found paths \ n " ) ; p r i n t f ( " Paths : \ t 00\ t 01 \ t 02 \ t 03 \ t 04 \ t 05 \ t 06 \ t 07 \ t 08 \ t 09\n " ) ; p r i n t f ( " \n " ) ; f o r ( my $ i i = 1 ; $ i i <= $ p a t h _ s h o r t e s t { " s h o r t e s t path max " } + 2 ; $ i i ++) { p r i n t f ( " SP : %4. i | \ t " , $ i i ) ; f o r ( my $ j j = 0 ; $ j j <= 1 0 ; $ j j ++) # a c t i v e p a t h s { p r i n t f ( " %2. i \ t " , $ r p _ p er f o r m ace [ $ i i ] [ $ j j ] ) ; } p r i n t f ( " \n " ) ; } p r i n t f ( " column 00 > double z er o i n t e r v a l . . . ERRORS . . . \ n " ) ; } } sub c o n n e c t i o n _ i n f o { # Us e r i n t e r f a c e t o p l o t d i f f e r e n t data f o r one c o n n e c t i o n my $ co nnect i o n my $ s r c my $ d s t # r t a b l e s p a c e time my $ p a t h _ t o t a l my @timeline_up_temp my @timeline_down_temp my $ t i m e _ s _ t _ s l o t s _ t o t a l # rta b l e source my $path_180_ave my $path_180_max my $ p a t h _ s h o r t e s t = s h i f t ( @_ ) ; = = $ s r c _ d e s t { $ co nnect i o n } { " s r c " } ; $ s r c _ d e s t { $ co nnect i o n } { " d s t " } ;

= $ s r c _ d e s t _ p a t h { $ s r c } { $ d s t } { "num paths " } ; = @{ $ t i m e l i n e _ u p [ $ s r c ] [ $ d s t ] } ; = @{ $timeline_down [ $ s r c ] [ $ d s t ] } ; = $ p at h_ t i m e_ s _ t { $ s r c } { $ d s t } { "num s l o t s " } ;

= $ p at h_ t i m e_ s r c { $ s r c } { $ d s t } { " 180 time ave " } ; = $ p at h_ t i m e_ s r c { $ s r c } { $ d s t } { " 180 time max " } ; = $ p at h_ t i m e_ s r c { $ s r c } { $ d s t } { " s h o r t e s t path " } ;

my $menu = 1 ; # c o n t r o l menu w hi l e ( $menu ) { p r i n t f ( " \n\n " ) ; p r i n t f ( " # # \ n " ) ; p r i n t f ( " # INFO FOR CONNECTION %s # \ n " , $ co nnect i o n ) ; p r i n t f ( " # # \ n " ) ; p r i n t f ( " \ n\ n " ) ; p r i n t f ( " SRC : %s \ t DEST : %s \ n " , $ s r c , $ d s t ) ; p r i n t f ( " SHORTEST PATH : %s \ n " , $ p a t h _ s h o r t e s t ) ; p r i n t f ( " PATHS TOTAL : %s \ n " , $ p a t h _ t o t a l ) ; p r i n t f ( " ACTIVE #PATH AVG : %s \ n " , $path_180_ave ) ; p r i n t f ( " ACTIVE #PATH MAX : %s \ n " , $path_180_max ) ; p r i n t " \n " ; p r i n t " \n " ; p r i n t " \n " ; p r i n t " PathTime PLOT 1\n" ; p r i n t " PathTime TEXT 2\n " ; p r i n t " Found paths i n r o u t i n g t a b l e PLOT 3\n " ; p r i n t " Make animated GIF 4\n " ;

177

A.3. Perl

print print print print print print

"DEBUG : "DEBUG : "DEBUG : "DEBUG : " \n" ; " RETURN

Make List List List

animated GIF s m al l a l l paths a l l UPEVENTS a l l DOWN_EVENTS

5\n " 6\n " 7\ n " 8\ n "

; ; ; ;

0\n " ;

$menu = <STDIN > ; chomp $menu ; i f ( $menu eq 1 ) { # PLOT : PathTime p l o t _ p at h_ t i m e ( $ co nnect i o n ) ; } e l s i f ( $menu eq 2 ) { # TEXT : PathTime show_path ( $ co nnect i o n ) ; } e l s i f ( $menu eq 3 ) { #PLOT : a c t i v e p a t h s from time $ s t a r t t o time $end # save eps my $ f o l d e r = " temp " ; my $ f i l enam e = " non " ; my $ s t a r t = 1 ; my $end = 0 ; # show p a t h s o v e r time ab w hi l e ( $ s t a r t > 0) { p r i n t f ( " \ n P l o t a l l found paths i n the r o u t i n g " . " t a b l e o v er a g i v en time i n t e r v a l \ n " ) ; p r i n t f ( " RETURN => 0\n " ) ; p r i n t f ( " \n " ) ; p r i n t f ( " f i r s t time s l o t : 1 %s \ n " , $ t i m e _ s _ t _ s l o t s _ t o t a l 1 ) ; $ s t a r t = <STDIN > ; chomp $ s t a r t ; p r i n t f ( " l a s t time s l o t : %s %s \ n " , $ s t a r t , $ t i m e _ s _ t _ s l o t s _ t o t a l 1 ) ; $end = <STDIN > ; chomp $end ;

i f ( $ s t a r t > 0 && $end <= $ t i m e _ s _ t _ s l o t s _ t o t a l ) # I n p u t v a l i d a t i o n { # f i n d a l l p a t h s t h a t were a c t i v e d u r i n g t h i s i n t e r v a l my @ a c t i v e _ p a t h _ i n t e r v a l my @active_path =(); =();

# c o n s t r u c t path l i s t f o r (my $ s l o t = $ s t a r t ; $ s l o t <= $end ; $ s l o t ++) # o v e r time { @active_path = @{ $ p a t h _ t i m e _ s _ t _ a c t i v e _ p a t h s [ $ s r c ] [ $ d s t ] [ $ s l o t ] } ; f o r ( my $path = 1 ; $path <= $ p a t h _ t o t a l ; $path ++) # o v e r p a t h s { i f ( $ a c t i v e _ p a t h [ $path ] > 0) { @ a c t i v e _ p a t h _ i n t e r v a l [ $path ] = 1 ; } } } # generate p l o t $ f i l enam e = s p r i n t f ( "%s /CON %sSRC%sDEST%sTIMESTART%i END%i " ,

178

A.3. Perl

$ f o l d e r , $ co nnect i o n , $ s r c , $dst , $ s t a r t , $end ) ; p l o t _ p at h_ s p a c e ( $ co nnect i o n , " $ f i l enam e . eps " , [ @ a c t i v e _ p a t h _ i n t e r v a l ] , " SLOT : $ s t a r t $end " ) ; # view p l o t p r i n t gv $ f i l enam e . eps ; } } } e l s i f ( $menu eq 4 ) { #make animated g i f p r i n t f ( " Make Animated G i f . . . . \ n " ) ; make_movie ( $ co nnect i o n ) ; } e l s i f ( $menu eq 5 ) { #make s m a l l animated g i f p r i n t f ( " Make Animated G i f s m al l . . . . \ n " ) ; p r i n t f ( " START SLOT : max%s \ n " , $ t i m e _ s _ t _ s l o t s _ t o t a l 1 ) ; my $ s t a r t = <STDIN > ; chomp $ s t a r t ; p r i n t f ( "END SLOT : max %s \ n " , $ t i m e _ s _ t _ s l o t s _ t o t a l 1 ) ; my $end = <STDIN > ; chomp $end ; make_movie_short ( $ co nnect i o n , $ s t a r t , $end ) ; } e l s i f ( $menu eq 6 ) { # l i s t a l l paths p r i n t f ( " Paths : \ n " ) ; f o r ( my $ i i = 1 ; $ i i <= $ p a t h _ t o t a l ; $ i i ++) { p r i n t f ( " \ t NR : %i \ t PATH : %s \ n " , $ i i , $src_dest_path { $s r c } { $dst } { $ i i } ) ; } } e l s i f ( $menu eq 7 ) { # l i s t a l l up e v e n t s p r i n t f ( " UP E v ent s : %i \ n " , s c a l a r ( @timeline_up_temp ) ) ; f o r ( my $ i i = 0 ; $ i i < s c a l a r ( @timeline_up_temp ) ; $ i i ++) { p r i n t f ( " \ t time : %f \ t number o f ev ent s %i \ t \ n " , $timeline_up_temp [ $ i i ] , $event_hash { $ s r c } { $ d s t } { " up " } { $timeline_up_temp [ $ i i ] } { "num ev ent s " } ) ; } } e l s i f ( $menu eq 8 ) { # l i s t a l l down e v e n t s p r i n t f ( "DOWN E v ent s : %i \ n " , s c a l a r ( @timeline_down_temp ) ) ; f o r ( my $ i i = 0 ; $ i i < s c a l a r ( @timeline_down_temp ) ; $ i i ++) { p r i n t f ( " \ t time : %f \ t number o f ev ent s %i \ t \ n " , $timeline_down_temp [ $ i i ] , $event_hash { $ s r c } { $ d s t } { " down " } { $timeline_down_temp [ $ i i ] } { "num ev ent s " } ) ; } } e l s i f ( $menu eq 0) { #retu rn

179

A.3. Perl

} else { p r i n t " unknown menu : $menu " ; } } p r i n t f ( " \n " ) ; printf ( " END INFO END \n " ) ; p r i n t f ( " \n " ) ; } sub show_path { # l i s t a l l path a t time x p r i n t f ( " show path \ n " ) ; # e x t r a c t p a t h s a t time x and d i s p l a y them i n A S C I I my $ co nnect i o n my $ s r c my $ d s t my $ p a t h _ t o t a l my $time = s h i f t (@_ ) ; = $ s r c _ d e s t { $ co nnect i o n } { " s r c " } ; = $ s r c _ d e s t { $ co nnect i o n } { " d s t " } ; = $ s r c _ d e s t _ p a t h { $ s r c } { $ d s t } { "num paths " } ; = 0;

my $ t i m e _ s l o t s _ t o t a l _ s _ t = $ p at h_ t i m e_ s _ t { $ s r c } { $ d s t } { "num s l o t s " } ; my @active_path =(); p r i n t f ( " show path f o r : SRC %s DEST %s TOTALPATHS %s NUM TIMESLOTS %s \ n " , $ s r c , $dst , $ p a t h _ t o t a l , $ t i m e _ s l o t s _ t o t a l _ s _ t ) ; f o r ( my $ i i = 1 ; $ i i < $ t i m e _ s l o t s _ t o t a l _ s _ t ; $ i i ++) { #update data $time = $ p at h_ t i m e_ s _ t { $ s r c } { $ d s t } { $ i i } { " time " } ; @active_path = @{ $ p a t h _ t i m e _ s _ t _ a c t i v e _ p a t h s [ $ s r c ] [ $ d s t ] [ $ i i ] } ; p r i n t f ( " \ nTIME : %s \ n " , $time ) ; f o r ( my $ j j = 0 ; $ j j <= $ p a t h _ t o t a l ; $ j j ++) { i f ( $ a c t i v e _ p a t h [ $ j j ] > 0) { p r i n t f ( " \ t \ tuptime %s r e l a t i v e %s path (% s ) %s \ n " , $ a c t i v e _ p a t h [ $ j j ] , $time $ a c t i v e _ p a t h [ $ j j ] , $ j j , $src_dest_path { $s r c } { $dst } { $ j j } ) ; } } } } sub make_movie ( ) { # make an animated g i f out o f t h e path s p a c e time i n f o f o r one c o n n e c t i o n # animation i s based on w h i r l g i f ( h t t p : / /www. danbbs . dk /~ d i n o / w h i r l g i f / ) my my my my $ co nnect i o n $src $dst $path_total = = = = s h i f t ( @_ ) ; $ s r c _ d e s t { $ co nnect i o n } { " s r c " } ; $ s r c _ d e s t { $ co nnect i o n } { " d s t " } ; $ s r c _ d e s t _ p a t h { $ s r c } { $ d s t } { "num paths " } ;

my $ t i m e _ s _ t _ s l o t s _ t o t a l

= $ p at h_ t i m e_ s _ t { $ s r c } { $ d s t } { "num s l o t s " } ;

# f o l d e r where t h e movie i s s a v e d

180

A.3. Perl

my $filename_movie my $ f o l d e r mkdir $ f o l d e r ; my $ w h i r l _ a r g my $TIME_SCALE_FACTOR

= " animatedSRC$ s r cDEST$ d s t " ; = " movie " ; = " " ; # argument f o r w h i r l = 10;

# v a r i a b l e s needed t o g e n e r a t e t h e p l o t s my @active_path = (); my $time = 0; my $time_next = 0; my $ s l o t = 0; my $ f i l enam e = ""; # data s t r u c t u r e t o remember t h e f i l e n a m e and time t o g e n e r a t e t h e movie my @f i l enam e_ co nt ai ner = (); my @time_container = (); my @d el ay _ co nt ai ner = (); # DEBUG OUT p r i n t f ( " \ n\ n make movie \n " ) ; # Generate eps # # # time z e r o f o r (my $ i i = 0 ; $ i i <= $ p a t h _ t o t a l ; $ i i ++) { $active_path [ $ i i ] = 0; } $slot = 0; $time = 0; $time_next = $ p at h_ t i m e_ s _ t { $ s r c } { $ d s t } { $ s l o t + 1 } { " time " } ; $ t i m e _ c o n t a i n e r [ 0 ] = $time ; $ d e l a y _ c o n t a i n e r [ 0 ] = i n t ( ( $time_next $time ) $TIME_SCALE_FACTOR ) ; $ f i l enam e = s p r i n t f ( "%s /CON %sSRC%sDEST%sTIME %012.6 f " , $ f o l d e r , $ co nnect i o n , $ s r c , $dst , $time ) ;

$ f i l e n a m e _ c o n t a i n e r [ 0 ] = $ f i l enam e ; p l o t _ p at h_ s p ac e ( $ co nnect i o n , " $ f i l enam e . eps " , [ @active_path ] , " TIME : $time $time_next IMAGE $ s l o t o f $ t i m e _ s _ t _ s l o t s _ t o t a l " ) ; # time 1 t o i n f i n i t y # s t a r t : s l o t = 1 end : s l o t = $ t i m e _ s _ t _ s l o t s _ t o t a l 1 f o r ( $ s l o t = 1 ; $ s l o t < $ t i m e _ s _ t _ s l o t s _ t o t a l ; $ s l o t ++) { # update data f o r time s l o t $ s l o t $time_next = $ p at h_ t i m e_ s _ t { $ s r c } { $ d s t } { $ s l o t + 1 } { " time " } ; $time = $ p at h_ t i m e_ s _ t { $ s r c } { $ d s t } { $ s l o t } { " time " } ; $time_container [ $s l o t ] = $time ;

$ d e l a y _ c o n t a i n e r [ $ s l o t ] = i n t ( ( $time_next $time ) $TIME_SCALE_FACTOR ) ; $ f i l enam e = s p r i n t f ( "%s /CON %sSRC%sDEST%sTIME %012.6 f " , $ f o l d e r , $ co nnect i o n , $ s r c , $dst , $time ) ; $ f i l e n a m e _ c o n t a i n e r [ $ s l o t ] = $ f i l enam e ; @active_path = @{ $ p a t h _ t i m e _ s _ t _ a c t i v e _ p a t h s [ $ s r c ] [ $ d s t ] [ $ s l o t ] } ; # create plot p l o t _ p at h_ s p a ce ( $ co nnect i o n , " $ f i l enam e . eps " , [ @active_path ] ,

181

A.3. Perl

" TIME : $time $time_next IMAGE $ s l o t o f $ t i m e _ s _ t _ s l o t s _ t o t a l " ) ; i f ( $DEBUG == 1 ) { p r i n t f ( " SLOT %4. i TIME % 1 2 . 6 f DELAY ABS % 1 2 . 6 f " . " DELAY SCALE ( 1 / 1 0 0 s ) % 1 2 . 6 f FILENAME : %s \ n " , $ s l o t , $time , ( $time_next $time ) , $ d e l a y _ c o n t a i n e r [ $ s l o t ] , $ f i l enam e ) ; } # view p l o t # p r i n t gv $ f i l e n a m e . eps ; } # G e n e r a t e Movie # # # # We used t h e w h i r l g i f t o c r e a t e our movie # Use c o n v e r t o f t h e ImageMagick P a c k e t t o c o n v e r t e p s t o g i f # o <outputfile > # t < delay > i n 1/100 s f o r ( my $ i i = 0 ; $ i i < $ t i m e _ s _ t _ s l o t s _ t o t a l ; $ i i ++) { p r i n t " c o n v e r t img $ i i o f $ t i m e _ s _ t _ s l o t s _ t o t a l \ n " ; # c o n ver t eps to g i f my $command = " c o n v e r t d e n s i t y 200 $ f i l e n a m e _ c o n t a i n e r [ $ i i ] . eps " . " $filename_container [ $ i i ] . g i f " ; p r i n t $command \ n ; # crop g i f $command = " c o n v e r t cr o p 640x600+200+80! $ f i l e n a m e _ c o n t a i n e r [ $ i i ] . g i f " . " $filename_container [ $ i i ] . g i f " ; p r i n t $command ; # c r e a t e t h e argument s t r i n g f o r w h i r l $whirl_arg = " $ w h i r l _ a r g time $ d e l a y _ c o n t a i n e r [ $ i i ] $ f i l e n a m e _ c o n t a i n e r [ $ i i ] . g i f " ; } # c r e a t e t h e animated g i f p r i n t " c r e a t e animated g i f : $filename_movie . g i f \ n " ; p r i n t $ w h i r l g i f o $filename_movie . g i f $ w hi r l _ ar g ; } sub make_movie_short ( ) { # DEBUG # l i k e make_movie but r e d u c e s i z e o f g i f my $ co nnect i o n my $ s l o t _ s t a r t my $ s l o t _ e n d my $ s r c my $ d s t my $ p a t h _ t o t a l = s h i f t (@_ ) ; = s h i f t (@_ ) ; = s h i f t (@_ ) ; = $ s r c _ d e s t { $ co nnect i o n } { " s r c " } ; = $ s r c _ d e s t { $ co nnect i o n } { " d s t " } ; = $ s r c _ d e s t _ p a t h { $ s r c } { $ d s t } { "num paths " } ; = $ p at h_ t i m e_ s _ t { $ s r c } { $ d s t } { "num s l o t s " } ;

...

my $ t i m e _ s _ t _ s l o t s _ t o t a l

# f o l d e r where t h e movie i s s a v e d my $filename_movie = " animatedgif s ho r tSRC$ s r cDEST$ d s t " ; my $ f o l d e r = " movie " ; mkdir $ f o l d e r ;

182

A.3. Perl

my $ w h i r l _ a r g my $TIME_SCALE_FACTOR

= ""; = 10;

# v a r i a b l e s needed t o g e n e r a t e t h e p l o t s my @active_path = (); my $time = 0; my $time_next = 0; my $ s l o t = 0; my $ f i l enam e = ""; # data s t r u c t u r e t o remember t h e f i l e n a m e and time t o g e n e r a t e t h e movie my @f i l enam e_ co nt ai ner = ( ) ; my @time_container =(); my @d el ay _ co nt ai ner =(); # DEBUG OUT p r i n t f ( " \ n\ n make movie \n " ) ; # Generate eps # # i f ( $ s l o t _ s t a r t == 0) { # time z e r o f o r ( my $ i i = 0 ; $ i i <= $ p a t h _ t o t a l ; $ i i ++) { $active_path [ $ i i ] = 0; } $slot = 0; $time = 0; $time_next = $ p at h_ t i m e_ s _ t { $ s r c } { $ d s t } { $ s l o t + 1 } { " time " } ; $ t i m e _ c o n t a i n e r [ 0 ] = $time ; $ d e l a y _ c o n t a i n e r [ 0 ] = i n t ( ( $time_next $time ) $TIME_SCALE_FACTOR ) ; $ f i l enam e = s p r i n t f ( "%s /CON %sSRC%sDEST%sTIME %012.6 f " , $ f o l d e r , $ co nnect i o n , $ s r c , $dst , $time ) ;

$ f i l e n a m e _ c o n t a i n e r [ 0 ] = $ f i l enam e ; p l o t _ p at h_ s p a ce ( $ co nnect i o n , " $ f i l enam e . eps " , [ @active_path ] , " TIME : $time $time_next " ) ; $slot = 1 ; } else { $slot = $slot_start ; } # time 1 t o i n f i n i t y # s t a r t : s l o t = 1 end : s l o t = $ t i m e _ s _ t _ s l o t s _ t o t a l 1 f o r ( ; $ s l o t < $ s l o t _ e n d ; $ s l o t ++) { # update data f o r time s l o t $ s l o t $time_next = $ p at h_ t i m e_ s _ t { $ s r c } { $ d s t } { $ s l o t + 1 } { " time " } ; $time = $ p at h_ t i m e_ s _ t { $ s r c } { $ d s t } { $ s l o t } { " time " } ; $ d e l a y _ c o n t a i n e r [ $ s l o t ] = i n t ( ( $time_next $time ) $TIME_SCALE_FACTOR ) ; $ t i m e _ c o n t a i n e r [ $ s l o t ] = $time ; $ f i l enam e = s p r i n t f ( "%s /CON %sSRC%sDEST%sTIME %012.6 f " , $ f o l d e r , $ co nnect i o n , $ s r c , $dst , $time ) ; $ f i l e n a m e _ c o n t a i n e r [ $ s l o t ] = $ f i l enam e ; @active_path # create plot = @{ $ p a t h _ t i m e _ s _ t _ a c t i v e _ p a t h s [ $ s r c ] [ $ d s t ] [ $ s l o t ] } ;

183

A.3. Perl

p l o t _ p at h_ s p ac e ( $ co nnect i o n , " $ f i l enam e . eps " , [ @active_path ] , " TIME : $time $time_next " ) ; i f ( $DEBUG == 1 ) { p r i n t f ( " SLOT %4. i TIME % 1 2 . 6 f DELAY ABS % 1 2 . 6 f " . " DELAY SCALE ( 1 / 1 0 0 s ) % 1 2 . 6 f FILENAME : %s \ n " , $ s l o t , $time , ( $time_next $time ) , $ d e l a y _ c o n t a i n e r [ $ s l o t ] , $ f i l enam e ) ; } # view p l o t # p r i n t gv $ f i l e n a m e . eps ; } # G e n e r a t e Movie # # # We used t h e w h i r l g i f t o c r e a t e our movie # Use c o n v e r t o f t h e ImageMagick P a c k e t t o c o n v e r t e p s t o g i f # o <outputfile > # t < delay > i n 1/100 s f o r ( my $ i i = $ s l o t _ s t a r t ; $ i i < $ s l o t _ e n d ; $ i i ++) { i f ( $ d e l a y _ c o n t a i n e r [ $ i i ] > 5 ) # p r o c e s s o n l y v i s i b l e changes { p r i n t " c o n v e r t img ( $ f i l e n a m e _ c o n t a i n e r [ $ i i ] ) $ i i o f $ t i m e _ s _ t _ s l o t s _ t o t a l \ n " ; # c o n ver t eps to g i f my $command = " c o n v e r t d e n s i t y 200 $ f i l e n a m e _ c o n t a i n e r [ $ i i ] . eps " . " $filename_container [ $ i i ] . g i f " ; p r i n t $command ; # crop g i f $command = " c o n v e r t cr o p 640x600+200+80! $ f i l e n a m e _ c o n t a i n e r [ $ i i ] . g i f " . " $filename_container [ $ i i ] . g i f " ; p r i n t $command ; # c r e a t e t h e argument s t r i n g f o r w h i r l $ w h i r l _ a r g = " $ w h i r l _ a r g time $ d e l a y _ c o n t a i n e r [ $ i i ] " . " $filename_container [ $ i i ] . g i f " ; } } # c r e a t e t h e animated g i f p r i n t " c r e a t e animated g i f : $filename_movie . g i f \ n " ; p r i n t $ w h i r l g i f o $filename_movie . g i f $ w hi r l _ ar g ; } sub p l o t _ p at h_ t i m e { # p l o t number o f p a t h s o v e r t h e time my $ co nnect i o n my $ s r c my $ d s t my $ I N F I N I T Y # r t a b l e s p a c e time my $ s _ t _ t i m e my $ s _ t _ t i m e _ s l o t _ t o t a l my $ s _ t _ a c t i v e _ p a t h s my $ s _ t _ av er ag e _ p a t hs = s h i f t ( @_ ) ; = $ s r c _ d e s t { $ co nnect i o n } { " s r c " } ; = $ s r c _ d e s t { $ co nnect i o n } { " d s t " } ; = 99999999;

= = = =

0; $ p at h_ t i m e_ s _ t { $ s r c } { $ d s t } { "num s l o t s " } ; 0; 0 ; #$ p a t h _ t i m e _ s _ t { $ s r c } { $ d s t } { " time a v e r a ge " } ;

184

A.3. Perl

# rtable src my $ s r c _ t i m e my $ s r c _ t i m e _ s l o t _ t o t a l my $ s r c _ a c t i v e _ p a t h s my $ s r c _ a v e r a g e _ p a t h s _ 1 8 0 # gn u p l o t my $ d a t a _ f i l e _ s _ t my $ d a t a _ f i l e _ s r c my $ h e a d e r _ f i l e my $ o u t p u t _ f i l e my $max_slots

= = = =

0; $ p at h_ t i m e_ s r c { $ s r c } { $ d s t } { "num s l o t s " } ; 0; $ p at h_ t i m e_ s r c { $ s r c } { $ d s t } { " 180 avg " } ;

= = = = =

" g nup l o t _ d at a_ p at hs _ t i m e_ s _ t . tmp " ; " g nup l o t _ d at a_ p a t h s _ t i m e_ s r c . tmp " ; " gnuplot_head er . tmp " ; " $ s r c$dstpathtime . eps " ; 0;

# w r i t e data f i l e p r i n t " g ener at e gnu data f i l e

. . . \n " ;

#rtable_s_t open ( GNUPLOT_DATA , " > $ f o l d er _ t em p / $ d a t a _ f i l e _ s _ t " ) | | d i e " cant w r i t e g nup l o t _ d at a . tmp f i l e " ; f o r (my $ i i = 0 ; $ i i < $ s _ t _ t i m e _ s l o t _ t o t a l ; $ i i ++) { # time update $s_t_time = $ p at h_ t i m e_ s _ t { $ s r c } { $ d s t } { $ i i } { " time " } ; # p l o t o l d data an new time : ( d a t a p o i n t 1 ) # 0 1 : r t a b l e _ s _ t : time p r i n t GNUPLOT_DATA ( $ s _ t _ t i m e , " \ t " ) ; # 0 2 : r t a b l e _ s _ t : number o f a c t i v e p a t h s p r i n t GNUPLOT_DATA ( $ s _ t _ a c t i v e _ p a t h s , " \ t " ) ; # 0 3 : r t a b l e _ s _ t : number o f p a t h s on a v e r a ge p r i n t GNUPLOT_DATA ( $ s _ t _ av er ag e_ p at hs , " \ t " ) ; p r i n t GNUPLOT_DATA ( " \ n " ) ; #update data $s_t_active_paths

= $ p at h_ t i m e_ s _ t { $ s r c } { $ d s t } { $ i i } { "num a c t i v e paths " } ;

# p l o t new data a t new time : ( d a t a p o i n t 2 ) # 0 1 : r t a b l e _ s _ t : time p r i n t GNUPLOT_DATA ( $ s _ t _ t i m e , " \ t " ) ; # 0 2 : r t a b l e _ s _ t : number o f a c t i v e p a t h s p r i n t GNUPLOT_DATA ( $ s _ t _ a c t i v e _ p a t h s , " \ t " ) ; # 0 3 : r t a b l e _ s _ t : number o f p a t h s on a v e r a ge p r i n t GNUPLOT_DATA ( $ s _ t _ av er ag e_ p at hs , " \ t " ) ; p r i n t GNUPLOT_DATA ( " \ n " ) ; } # l a s t point i n the i n f i n i t y # 0 1 : r t a b l e _ s _ t : time p r i n t GNUPLOT_DATA ( $ I NF I NI T Y , " \ t " ) ; # 0 2 : r t a b l e _ s _ t : number o f a c t i v e p a t h s p r i n t GNUPLOT_DATA ( $ s _ t _ a c t i v e _ p a t h s , " \ t " ) ; # 0 3 : r t a b l e _ s _ t : number o f p a t h s on a v e r a ge p r i n t GNUPLOT_DATA ( $ s _ t _ av er ag e_ p at hs , " \ t " ) ; c l o s e ( GNUPLOT_DATA ) ; #rtable_src

185

A.3. Perl

open ( GNUPLOT_DATA , " > $ f o l d er _ t em p / $ d a t a _ f i l e _ s r c " ) | | d i e " cant w r i t e g nup l o t _ d at a . tmp f i l e " ; f o r ( my $ i i = 0 ; $ i i < $ s r c _ t i m e _ s l o t _ t o t a l ; $ i i ++) { # time update $ s r c _ t i m e = $ p at h_ t i m e_ s r c { $ s r c } { $ d s t } { $ i i } { " time " } ; # p l o t o l d data an new time : ( d a t a p o i n t 1 ) # 0 1 : r t a b l e _ s r c : time p r i n t GNUPLOT_DATA ( $ s r c_ t i m e , " \ t " ) ; # 0 2 : r t a b l e _ s r c : number o f a c t i v e p a t h s p r i n t GNUPLOT_DATA ( $ s r c _ a c t i v e _ p a t h s , " \ t " ) ; # 0 3 : r t a b l e _ s r c : number o f p a t h s on a v e r a ge p r i n t GNUPLOT_DATA ( $ s r c_ av er ag e_ p at hs _ 1 8 0 , " \ t " ) ; p r i n t GNUPLOT_DATA ( " \ n " ) ; #update data $ s r c _ a c t i v e _ p a t h s = $ p at h_ t i m e_ s r c { $ s r c } { $ d s t } { $ i i } { "num paths " } ; # p l o t new data a t new time : ( d a t a p o i n t 2 ) # 0 1 : r t a b l e _ s r c : time p r i n t GNUPLOT_DATA ( $ s r c_ t i m e , " \ t " ) ; # 0 2 : r t a b l e _ s r c : number o f a c t i v e p a t h s p r i n t GNUPLOT_DATA ( $ s r c _ a c t i v e _ p a t h s , " \ t " ) ; # 0 3 : r t a b l e _ s r c : number o f p a t h s on a v e r a ge p r i n t GNUPLOT_DATA ( $ s r c_ av er ag e_ p at hs _ 1 8 0 , " \ t " ) ; p r i n t GNUPLOT_DATA ( " \ n " ) ; } # l a s t point i n the i n f i n i t y # 0 1 : r t a b l e _ s r c : time p r i n t GNUPLOT_DATA ( $ I NF I NI T Y , " \ t " ) ; # 0 2 : r t a b l e _ s r c : number o f a c t i v e p a t h s p r i n t GNUPLOT_DATA ( $ s r c _ a c t i v e _ p a t h s , " \ t " ) ; # 0 3 : r t a b l e _ s r c : number o f p a t h s on a v e r a ge p r i n t GNUPLOT_DATA ( $ s r c_ av er ag e_ p at hs _ 1 8 0 , " \ t " ) ; c l o s e ( GNUPLOT_DATA ) ;

#w r i t e header f i l e # p r i n t " g e n e r a t e gnu

plot . . . \ n ";

open ( GNUPLOT_HEADER , " > $ f o l d er _ t em p / $ h e a d e r _ f i l e " ) | | d i e " cant w r i t e gnuplot_header . tmp f i l e " ; p r i n t GNUPLOT_HEADER ( " #G ener al S e t t i n g s s e t output \ " $ f o l d er _ t em p / $ o u t p u t _ f i l e \ " s e t term p o s t s c r i p t eps enhanced c o l o r set s i z e 0 . 7 , 0 . 7 #s e t xrange [ 0 : 1 0 0 0 ] #s e t yrange [ 0 : 2 0 ]

186

A.3. Perl

# presentation s e t xrange [ 3 0 0 : 3 5 0 ] s e t yrange [ 0 : 2 . 5 ] s e t t i t l e \ " Number o f paths on average o v er time \ " f o n t \ " H e l v e t i c a Bold , 1 4 \ " s e t x l a b e l \ " time [ s ] \ " s e t y l a b e l \ " number o f paths \ " # Presentation # plot \ " $ f o l d er _ t em p / $ d a t a _ f i l e _ s _ t \ " us i ng 1 : 2 " . " t i t l e \"# paths r o u t i n g t a b l e \ " with l i n e s l i n e t y p e 1 l i n e w i d t h 2 , \ \ # \ " $ f o l d er _ t em p / $ d a t a _ f i l e _ s r c \ " us i ng 1 : 2 " . " t i t l e \"# paths s o ur ce \ " with l i n e s l i n e t y p e 3 l i n e w i d t h 2 , \ \ # \ " $ f o l d er _ t em p / $ d a t a _ f i l e _ s r c \ " us i ng 1 : 3 " . " t i t l e \"# paths avg \ " with l i n e s l i n e t y p e 4 l i n e w i d t h 2 plot \ " $ f o l d er _ t em p / $ d a t a _ f i l e _ s r c \ " us i ng 1 : 2 " . " t i t l e \"# paths \ " with l i n e s l i n e t y p e 1 l i n e w i d t h 2 , \ \ \ " $ f o l d er _ t em p / $ d a t a _ f i l e _ s r c \ " us i ng 1 : 3 " . " t i t l e \"# paths time avg \ " with l i n e s l i n e t y p e 3 l i n e w i d t h 2

" ); c l o s e ( GNUPLOT_HEADER ) ; # make g r a p h i c p r i n t gnuplot $ f o l d er _ t em p / $ h e a d e r _ f i l e ; # view p l o t p r i n t gv $ f o l d er _ t em p / $ o u t p u t _ f i l e ; } sub p l o t _ p a t h _ s h o r t e s t { # p l o t number o f p a t h s found on a v e r a ge o v e r s h o r t e s t path my $ I N F I N I T Y my $path_shortest_max my $path_number_180_time_avg my $path_number_180_time_std my $path_number_180_max_avg my $path_number_180_max_std = 99999999; = $ p a t h _ s h o r t e s t { " s h o r t e s t path max " } ; = 0; = 0; = 0; = 0;

my $path_number_180_rp_p_avg my $path_number_180_rp_p_std my $ co nnect i o n s my $ r o u t e _ r e q u e s t s # gn u p l o t my $ d a t a _ f i l e my $ h e a d e r _ f i l e my $ o u t p u t _ f i l e # w r i t e data f i l e p r i n t " g ener at e gnu data f i l e

= 0; = 0; = 0; = 0;

= " g n u p l o t _ d a t a _ s t a t _ p a t h _ s h o r t e s t . tmp " ; = " g n u p l o t _ h e a d e r _ s t a t _ p a t h _ s h o r t e s t . tmp " ; = " s t a t _ p a t h _ s h o r t e s t _ p a t h . eps " ;

. . . \n " ;

open ( GNUPLOT_DATA , " > $ f o l d er _ t em p / $ d a t a _ f i l e " ) | | d i e " can t w r i t e g nup l o t _ d at a . tmp f i l e " ; f o r (my $ i i = 1 ; $ i i <= $path_shortest_max ; $ i i ++) { #update data

187

A.3. Perl

$path_number_180_time_avg $path_number_180_time_std $path_number_180_max_avg $path_number_180_max_std $path_number_180_rp_p_avg $path_number_180_rp_p_std $ co nnect i o ns $route_requests

= $ p a t h _ s h o r t e s t { $ i i } { " 180 time avg " } ; = s q r t ( $ p a t h _ s h o r t e s t { $ i i } { " 180 time v a r " } ) ; = $ p a t h _ s h o r t e s t { $ i i } { " 180 max avg " } ; = s q r t ( $ p a t h _ s h o r t e s t { $ i i } { " 180 max v a r " } ) ; = $ p a t h _ s h o r t e s t { $ i i } { " 180 rp_p avg " } ; = s q r t ( $ p a t h _ s h o r t e s t { $ i i } { " 180 rp_p v a r " } ) ; = $ p a t h _ s h o r t e s t { $ i i } { "num con " } ; = $ p a t h _ s h o r t e s t { $ i i } { " 180 rp_p num r r e q " } / 1 0 0 ;

# p l o t new data a t new time : ( d a t a p o i n t 2 ) # 0 1 : s h o r t e s t path p r i n t GNUPLOT_DATA ( " $ i i \ t " ) ; # 180 # 0 2 : number o f samples p r i n t GNUPLOT_DATA ( " $ co nnect i o n s \ t " ) ; # 0 3 : number o f path found on a v e r a ge p r i n t GNUPLOT_DATA ( " $path_number_180_time_avg \ t " ) ; # 0 4 : sigma = s q r t ( v a r i a n c e ) o f 03 p r i n t f GNUPLOT_DATA ( " $path_number_180_time_std\ t " ) ; # 0 5 : max found path ( avg o v e r a l l c o n n e c t i o n s ) p r i n t GNUPLOT_DATA ( " $path_number_180_max_avg \ t " ) ; # 06: sigma = s q r t ( v a r i a n c e ) o f 05 p r i n t GNUPLOT_DATA ( " $path_number_180_max_std \ t " ) ; # 07 number o f r o u t e r e q u e s t p r i n t GNUPLOT_DATA ( " $ r o u t e _ r e q u e s t s \ t " ) ; # 0 8 : number o f path found by one r r e q p r i n t GNUPLOT_DATA ( " $path_number_180_rp_p_avg \ t " ) ; # 09: sigma = s q r t ( v a r i a n c e ) o f 08 p r i n t f GNUPLOT_DATA ( " $path_number_180_rp_p_std\ t " ) ; p r i n t GNUPLOT_DATA ( " \ n " ) ; } c l o s e ( GNUPLOT_DATA ) ; #w r i t e header f i l e p r i n t " g ener at e gnu header f i l e . . . \ n " ; open ( GNUPLOT_HEADER , " > $ f o l d er _ t em p / $ h e a d e r _ f i l e " ) | | d i e " can t w r i t e gnuplot_header . tmp f i l e " ; p r i n t GNUPLOT_HEADER ( " #G ener al S e t t i n g s s e t output \ " $ f o l d er _ t em p / $ o u t p u t _ f i l e \ " s e t term p o s t s c r i p t eps enhanced c o l o r set s i z e 0 . 7 , 0 . 7 s e t xrange [ 1 : $path_shortest_max ] s e t yrange [ 0 : 7 ] s e t y2range [ 0 : 2 0 ] set x t i c s 1 , 1 set y t i c s 0 , 1

188

A.3. Perl

set y 2 t i c s 0 , 5 s e t y t i c s no m i r r o r s e t t i t l e \ " Paths found on average f o r a s h o r t e s t path with x hops ( t > 1 8 0 ) \ " " . " f o n t \ " H e l v e t i c a Bold , 1 4 \ " s e t x l a b e l \ " hops \ " s e t y l a b e l \ " number o f paths \ " # Presentation # s e t y 2 l a b e l \ " number o f samples \ " s e t y 2 l a b e l \ " number o f co nnect i o ns \ " # Presentation #p l o t \ " $ f o l d er _ t em p / $ d a t a _ f i l e \ " us i ng 1 : 5 : 6 a x i s x 1 y 1 " . " t i t l e \ " paths max \ " with y e r r o r l i n e s l i n e t y p e 1 l i n e w i d t h 2 , \ \ # \ " $ f o l d er _ t em p / $ d a t a _ f i l e \ " us i ng 1 : 3 : 4 a x i s x 1 y 1 " . " t i t l e \ " paths avg \ " with y e r r o r l i n e s l i n e t y p e 3 l i n e w i d t h 2 , \ \ # \ " $ f o l d er _ t em p / $ d a t a _ f i l e \ " us i ng 1 : 8 : 9 a x i s x 1 y 1 " . " t i t l e \ " paths a f t e r one RREQ \ " with y e r r o r l i n e s l i n e t y p e 4 l i n e w i d t h 2 , \ \ # \ " $ f o l d er _ t em p / $ d a t a _ f i l e \ " us i ng 1 : 2 axis x1y2 " . " t i t l e \ " #co nnect i o ns \ " with l i n e s l i n e t y p e 5 l i n e w i d t h 2 , \ \ # \ " $ f o l d er _ t em p / $ d a t a _ f i l e \ " us i ng 1 : 7 axis x1y2 " . " t i t l e \ " #r r e q ( i n 1 0 0 ) \ " with l i n e s l i n e t y p e 8 l i n e w i d t h 2 \ \ plot \ " $ f o l d er _ t em p / $ d a t a _ f i l e \ " us i ng 1 : 3 : 4 a x i s x 1 y 1 " . " t i t l e \ " paths avg on time \ " with y e r r o r l i n e s l i n e t y p e 3 l i n e w i d t h 2 , \ \ \ " $ f o l d er _ t em p / $ d a t a _ f i l e \ " us i ng 1 : 8 : 9 a x i s x 1 y 1 " . " t i t l e \ " paths a f t e r one RREQ \ " with y e r r o r l i n e s l i n e t y p e 4 l i n e w i d t h 2 , \ \ \ " $ f o l d er _ t em p / $ d a t a _ f i l e \ " us i ng 1 : 2 axis x1y2 " . " t i t l e \ " # co nnect i o ns \ " with l i n e s l i n e t y p e 5 l i n e w i d t h 2 \ \

" ); c l o s e ( GNUPLOT_HEADER ) ; # make g r a p h i c p r i n t gnuplot $ f o l d er _ t em p / $ h e a d e r _ f i l e ; # view p l o t p r i n t gv $ f o l d er _ t em p / $ o u t p u t _ f i l e ; } sub dropzone { # p l o t dropped p a c k e t # gn u p l o t my $ d a t a _ f i l e my $ h e a d e r _ f i l e my $ o u t p u t _ f i l e

= " gnuplot_data_ drop zone . tmp " ; = " gnuplot_header_d ropzone . tmp " ; = " dropzone . eps " ;

# w r i t e data f i l e p r i n t " g ener at e gnu data f i l e

. . . \n " ;

open ( GNUPLOT_DATA , " > $ f o l d er _ t em p / $ d a t a _ f i l e " ) | | d i e " can t w r i t e g nup l o t _ d at a . tmp f i l e " ; f o r (my $ i i = 0 ; $ i i < $ n o d e _ t o t a l ; $ i i ++) { # 0 1 : node number #a p r i n t GNUPLOT_DATA ( $ i i , " \ t " ) ; # 02: X p o s i t i o n p r i n t GNUPLOT_DATA ( $ p o s i t i o n_ x _ no d e [ $ i i ] , " \ t " ) ; # 03: Y p o s i t i o n p r i n t GNUPLOT_DATA ( $ p o s i t i o n _ y _ n o d e [ $ i i ] , " \ t " ) ;

189

A.3. Perl

# 0 4 : dropped data p a c k e t o f node #a o v e r t o t a l s e n t data p a c k e t p r i n t GNUPLOT_DATA ( $ d r o p p ed _ d p ack e t s _ v _ t o t _ s en t [ $ i i ] , " \ t " ) ; # 0 5 : dropped data p a c k e t o f node #a o v e r r e c e i v e d data p a c k e t by node #a p r i n t GNUPLOT_DATA ( $ d r o p p ed _ d p acket s _ v _ r ecei v ed _ no d e [ $ i i ] , " \ t " ) ; p r i n t GNUPLOT_DATA ( " \ n " ) ; } c l o s e ( GNUPLOT_DATA ) ; #w r i t e header f i l e p r i n t " g ener at e gnu header . . . \ n " ; open ( GNUPLOT_HEADER , " > $ f o l d er _ t em p / $ h e a d e r _ f i l e " ) | | d i e " can t w r i t e gnuplot_head er . tmp f i l e " ; p r i n t GNUPLOT_HEADER ( " #G ener al S e t t i n g s s e t output \ " $ f o l d er _ t em p / $ o u t p u t _ f i l e \ " s e t term p o s t s c r i p t eps enhanced c o l o r set s i z e 1 , 2 s e t o r i g i n 0 ,0 set multiplot

# M u l t i p l o t MAP # # s e t nokey s e t pm3d s e t s i z e square s e t view map #make a g r i d out o f the s c a t t e r data #( be c a r e f u l l with paramater s e t t i n g s ) # < r o w _ s i z e > < c o l _ s i z e > <norm> # ( l i k e a low pass f i l t e r ) s e t d g r i d 3 d 1 0 0 , 1 0 0 , 16 s e t xrange [ 0 : 1 6 0 0 ] s e t yrange [ 0 : 1 6 0 0 ] s e t zrange [ 0 : 1 ] set s i z e 1 , 1 set xlabel \ " X \ " set y l ab el \ " Y \ "

s e t x t i c s 500 s e t y t i c s 500

# l o s t data p acket o v er a l l s ent s e t t i t l e \ " Dropped data p a c k e t s o v er t o t a l s ent data p a c k e t s \ " " . " f o n t \ " H e l v e t i c a Bold , 1 4 \ " set o r i g i n 0 ,1 s e t cbrange [ 0 : 0 . 0 1 ]

190

A.3. Perl

s p l o t \ " $ f o l d er _ t em p / $ d a t a _ f i l e \ " us i ng 2 : 3 : 4 with pm3d

# l o s t data p acket o v er r e c e i v e d s e t t i t l e \ " Dropped data p acket o v er r e c e i v e d data p acket o f t h i s node \ " " . " f o n t \ " H e l v e t i c a Bold , 1 4 \ " s e t o r i g i n 0 ,0 s e t cbrange [ 0 : 0 . 1 0 ] s p l o t \ " $ f o l d er _ t em p / $ d a t a _ f i l e \ " us i ng 2 : 3 : 5 with pm3d #end MAP unset d g r i d 3 d unset pm3d # node p o s i t i o n marker set set set set set set set t i t l e \" \" xlabel \" \" ylabel \" \" noxtic noytic nokey pointsize 1

#map 1 set o r i g i n 0 ,1 s p l o t \ " $ f o l d er _ t em p / $ d a t a _ f i l e \ " us i ng 2 : 3 : 4 with p o i n t s #map 2 s e t o r i g i n 0 ,0 # INFOS : s p l o t \ " $ f o l d er _ t em p / $ d a t a _ f i l e \ " us i ng 2 : 3 : 5 with p o i n t s set x t i c set y t i c s e t key set nomultiplot \n " ) ;

7 7

7 7

c l o s e ( GNUPLOT_HEADER ) ; # make g r a p h i c p r i n t gnuplot $ f o l d er _ t em p / $ h e a d e r _ f i l e ; # view p l o t p r i n t gv $ f o l d er _ t em p / $ o u t p u t _ f i l e ; } sub p l o t _ p at h_ s p ac e { # p l o t p a t h s i n r t a b l e s p a c e time f o r $ c o n n e c t i o n f o r $ t i m e _ s l o t # interface my $ co nnect i o n = s h i f t (@_ ) ; my $plot_name = s h i f t (@_ ) ; my @active_path = @{ s h i f t ( @_ ) } ;

191

A.3. Perl

my $ l a b e l my $ s r c my $ d s t my $ p a t h _ t o t a l

= s h i f t ( @_ ) ; = $ s r c _ d e s t { $ co nnect i o n } { " s r c " } ; = $ s r c _ d e s t { $ co nnect i o n } { " d s t " } ; = $ s r c _ d e s t _ p a t h { $ s r c } { $ d s t } { "num paths " } ;

# gn u p l o t my $ d a t a _ f i l e my $ d a t a _ f i l e _ b a c k my $ h e a d e r _ f i l e my $ o u t p u t _ f i l e # variables

= = = =

" gnuplot_data_paths_rtable " ; " g n u p l o t _ d a t a _ p a t h s _ r t a b l e _ b a c k " ; # background " g n u p l o t _ h e a d e r _ p a t h s _ r t a b l e . tmp " ; " $plot_name " ;

my @hops_array = ( ) ; # s a v e hops o f path my my my my $src_x $src_y $dst_x $dst_y = = = = $ p o s i t i o n_ x _ no d e [ $ s r c $position_y_node [ $src $ p o s i t i o n_ x _ no d e [ $ d s t $position_y_node [ $dst ]; ]; ]; ];

#DEBUG OUT PARAMETER CHECK i f ( $DEBUG == 1 ) { p r i n t f ( " \ n p l o t _ p at h_ s p ac e \n " ) ; p r i n t f ( " SRC %4. i ( % 6 . 3 f , % 6 . 3 f ) DEST %4.2 i ( % 6 . 3 f , % 6 . 3 f ) \ n " , $ s r c , $ s r c_ x , $ s r c _ y , $dst , $dst_x , $ d s t _ y ) ; p r i n t f ( " Filename : %s \ n " , $ o u t p u t _ f i l e ) ; } #w r i t e data f i l e ( 3D ) # p r i n t " g e n e r a t e gnu data f i l e # LINKS ... \n " ;

open ( GNUPLOT_DATA , " > $ f o l d er _ t em p / $ d a t a _ f i l e " ) | | d i e " can t w r i t e $ d a t a _ f i l e # l o o p o v e r p a t h s o f @a c t i v e _ p a t h f o r ( my $ l o o p _ p at h = 1 ; $ l o o p _ p at h <= $ p a t h _ t o t a l ; $ l o o p _ p at h ++) {# over d i f f e r e n t paths i f ( $ a c t i v e _ p a t h [ $ l o o p _ p at h ] > 0) # path a c t i v e ? { #y e s @hops_array = s p l i t ( / / , $ s r c _ d e s t _ p a t h { $ s r c } { $ d s t } { $ l o o p _ p at h } ) ; f o r ( my $loop_hop = 0 ; $loop_hop < s c a l a r ( @hops_array ) ; $loop_hop ++) { # w r i t e data i f ( $ ho p s _ ar r ay [ $loop_hop ] =~ "D" && $ ho p s _ ar r ay [ $loop_hop ] =~ " S " ) { # Header

file " ;

} e l s i f ( $ ho p s _ ar r ay [ $loop_hop ] =~ m/ ( 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 ) / ) { # w r i t e l i n e from l a s t hop t o t h i s hop p r i n t GNUPLOT_DATA ( " $ p o s i t i o n_ x _ no d e [ $ ho p s _ ar r ay [ $loop_hop ] ] \ t " . " $ p o s i t i o n _ y _ n o d e [ $ ho p s _ ar r ay [ $loop_hop ] ] \ t 1 \ n " ) ; } } p r i n t GNUPLOT_DATA ( " \ n \ n " ) ; } } c l o s e ( GNUPLOT_DATA ) ; # BACKGROUND open ( GNUPLOT_DATA , " > $ f o l d er _ t em p / $ d a t a _ f i l e _ b a c k " ) | | d i e " can t w r i t e $ d a t a _ f i l e _ b a c k f i l e " ;

192

A.3. Perl

f o r (my $ i i = 0 ; $ i i < $ n o d e _ t o t a l ; $ i i ++) { # 0 1 : node number #a p r i n t GNUPLOT_DATA ( $ i i , " \ t " ) ; # 02: X p o s i t i o n p r i n t GNUPLOT_DATA ( $ p o s i t i o n_ x _ no d e [ $ i i ] , " \ t " ) ; # 03: Y p o s i t i o n p r i n t GNUPLOT_DATA ( $ p o s i t i o n _ y _ n o d e [ $ i i ] , " \ t " ) ; #0 4 : dropped data p a c k e t o f node #a o v e r t o t a l s e n t data p a c k e t p r i n t GNUPLOT_DATA ( $ d r o p p ed _ d p acke t s _ v _ t o t _ s e n t [ $ i i ] , " \ t " ) ; # 0 5 : dropped data p a c k e t o f node #a o v e r r e c e i v e d data p a c k e t by node #a p r i n t GNUPLOT_DATA ( $ d r o p p ed _ d p acket s _ v _ r ecei v ed _ no d e [ $ i i ] , " \ t " ) ; p r i n t GNUPLOT_DATA ( " \ n " ) ; } c l o s e ( GNUPLOT_DATA ) ; # w r i t e header f i l e # p r i n t " g e n e r a t e gnu

plot . . . \ n ";

open ( GNUPLOT_HEADER , " > $ f o l d er _ t em p / $ h e a d e r _ f i l e " ) | | d i e " can t w r i t e gnu header f i l e $ h e a d e r _ f i l e " ; p r i n t GNUPLOT_HEADER ( " #G ener al S e t t i n g s s e t output \ " $ o u t p u t _ f i l e \ " s e t term p o s t s c r i p t eps enhanced c o l o r set s i z e 1 , 1 s e t o r i g i n 0 ,0 set multiplot s e t nokey s e t s i z e square s e t view map s e t xrange [ 0 : 1 7 0 0 ] s e t yrange [ 0 : 1 6 0 0 ] s e t zrange [ 0 : 1 0 ] set xlabel \ " X \ " set y l ab el \ " Y \ " s e t x t i c s 500 s e t y t i c s 500 s e t t i t l e \ " Content o f r o u t i n g t a b l e s \ " f o n t \ " H e l v e t i c a Bold , 1 4 \ " # BACKGROUND ## dropped p acket s e t pm3d s e t s i z e square set dgrid3d 100 ,100 ,16 s e t cbrange [ 0 : 0 . 0 2 5 ] s p l o t \ " $ f o l d er _ t em p / $ d a t a _ f i l e _ b a c k \ " us i ng 2 : 3 : 4 with pm3d unset d g r i d 3 d unset pm3d

193

A.3. Perl

## l a b e l set l ab el 1 \ " $l ab el ## s o ur ce s e t arrow 1 from 0 , 0 , 20 to $ s r c_ x , $ s r c _ y , 20 back n o f i l l e d l i n e t y p e 1 l i n e w i d t h 2 ## d e s t i n a t i o n s e t arrow 2 from 0 , 0 , 20 to $dst_x , $ d s t _ y , 20 back n o f i l l e d l i n e t y p e 3 l i n e w i d t h 2 ## a l l nodes set noxtic set noytic s e t nokey set p o i nt s i z e 1 s p l o t \ " $ f o l d er _ t em p / $ d a t a _ f i l e _ b a c k \ " us i ng 2 : 3 : 4 with p o i n t s set noxtic set noytic s e t nokey set p o i nt s i z e 1 s p l o t \ " $ f o l d er _ t em p / $ d a t a _ f i l e _ b a c k \ " us i ng 2 : 3 : 4 with p o i n t s # LINKS set p o i nt s i z e 2 s p l o t \ " $ f o l d er _ t em p / $ d a t a _ f i l e \ " us i ng 1 : 2 : 3 with l i n e s # node p o s i t i o n marker set set set set set set set t i t l e \" \" xlabel \" \" ylabel \" \" noxtic noytic nokey pointsize 2 1 6 1 6 \ " at 0 , 300 l e f t f r o n t

7 7

3 3

s p l o t \ " $ f o l d er _ t em p / $ d a t a _ f i l e \ " us i ng 1 : 2 : 3 with p o i n t s \n " ) ; c l o s e ( GNUPLOT_HEADER ) ; # make g r a p h i c p r i n t gnuplot $ f o l d er _ t em p / $ h e a d e r _ f i l e ; }

Listing A.11: analysis_one_run.pl

194

A.3. Perl

A.3.6. analysis_multiple_runs.pl
#! / usr / bin / p e r l # # ANALYSIS_MULTIPLE_RUNS . PL F I L E TO GENERATE S T A T I S T I C S OVER DIFFERENT . SIM F I L E S # # P r o j e c t : S e m e s t e r T h e s i s S S 06: # E v a l u a t i o n o f s c h e d u l i n g methods o v e r # m u l t i p a t h r o u t i n g i n w i r e l e s s m o b i l e Ad Hoc n e t w o r k s # # A u t h o r s : R e gu l a Goenner , Dominik Schatzmann # # [ Perl Script ] # # Date : J u l y 2006 # # I n p u t : [ s i m u l a t i o n data r e s u l t f o l d e r ] # # # Output : g r a p h i c s i n e p s format # # # Idea : # T h i s s c r i p t c a l c u l a t e s s t a t i s t i c data out o f d i f f e r e n t # s i m u l a t i o n r e s u l t s f i l e s ( . sim ) and p l o t t h i s v a l u e s with # t h e h e l p o f gn u p l o t # # Concept : # A p l o t can be c h a r a c t e r i z e by t h e t h r e e dimension xa x i s , ya x i s and # t h e p l o t t e d f u n c t i o n s ( zdim ) # # YDim ^ ZDim # | # | # | _________ > XDim # # We added an a d d i t i o n a l l y f i l t e r , c a l l e d F i x F i l t e r , t o s e l e c t t h e V e r s i o n # of the s i m u l a to r or d i f f e r e n t t o p o l o g i e s . # # To g e n e r a t e a p l o t with t h i s s c r i p t t h i s f o u r f i l t e r s have t o be s p e c i f i e d . # The s c r i p t then s e a r c h e s i n t h e f o l d e r o f t h e s i m u l a t i o n r e s u l t s f o r # t h e needed f i l e s and c a l c u l a t e s a l l data p o i n t s . # # # used command l i n e t o o l s : # # Filter : F i l t e r f u n c t i o n based on l s and gr e p # # Plot : P l o t s a r e ge n e r a t e d with gn u p l o t # # I m p l e m e n t a t i on : # # sub s e t _ f i l t e r T h i s fu n c ti o n i n i t s the f i l t e r s # # sub f i l e _ f i l t e r T h i s f u n c t i o n s e l e c t s t h e needed f i l e s t o b u i l d t h e s t a t i s t i c s # # sub s t a t i s t i c T h i s f u n c t i o n c a l c u l a t e s t h e s t a t i s t i c s o v e r d i f f e r e n t sim f i l e s # # sub gn u p l o t T h i s fu n c ti o n p l o t s the s t a t i s t i c s # # Usage : # S e t t h e parameter i n t h e SET PARAMETER p a r t # I f needed change t h e f i l t e r i n t h e s e t _ f i l t e r f u n c t i o n # # Known Bugs : # No Bugs r e p o r t e d ( 2 0 . 0 7 . 2 0 0 6 ) #

195

A.3. Perl

# behave l i k e a r e a s o n a b l e programming language use s t r i c t ; # Declaration of global v a r i a b l e s # # Filter my $ c h o i c e _ f i x ; my $ c h o i c e _ z ; my $ c h o i c e _ x ; my $ c h o i c e _ y ; # FIX my $ f i x _ g r e p ; my $ f i x _ t i t l e ; my $ f i x _ f i l e _ n a m e ; # ZValue my @z_dim_grep ; my @z _ l ab el ; my $ z _ f i l e_ nam e ; # XValue my @x_dim_grep ; my @x_data_point ; my $ x _ t i t l e ; my $ x _ a x i s ; my $ x _ t i c s ; my $x_range ; my $ x _ f i l e_ nam e ; # YValue my $ y _ t i t l e ; my $ y _ a x i s ; my $y_range ; my $ y _ t i c s ; my $ y _ f i l e_ nam e ; # # # # select select select select fix f il t er z filter x filter y filter

# gr e p p a t t e r n f o r t h e f i x f i l t e r # f i r s t part of the t i t l e # p a r t o f t h e output f i l e name

# gr e p p a t t e r n f o r t h e z f i l t e r # l a b e l f o r t h e zdimension # p a r t o f t h e output f i l e name

# gr e p p a t t e r n f o r t h e x f i l t e r # datapoint to pattern # # # # l a b e l a x i s i n gn u p l o t t i c s i n gn u p l o t range x a x i s p a r t o f t h e output f i l e name

# # # #

l a b e l a x i s i n gn u p l o t range y a x i s t i c s i n gn u l o t p a r t o f t h e output f i l e name

# S t a t i s t i c container my $ s t a t _ t y p e ; # chose type of s t a t i s t i c my @ s t a t i s t i c _ c o n t a i n e r ; # s t a t i s t i c c o n t a i n e r # 2D s t a t i s t i c [ zdim ] [ xdim ] [ . . . data . . . ] # F i l e container my @ f i l e _ t o _ s t a t ;

# a r r a y with f i l e n a m e s t h a t

# SET PARAMETER START # s w i t c h DEBUG on / o f f my $DEBUG = 0 ; # V e r s i o n & S i m u l a t i o n data my $ v e r s i o n = " D001 " ; my $ s i m u l a t i o n _ r e s u l t s = " . . / sim_data / $ v e r s i o n " ; my $ s i m u l a t i o n _ r e s u l t _ t y p e = " sim " ; # Check i f s i m u l a t i o n run u n t i l t h e end # ( I s sim f i l e OK ? ) my $ t _ f i r s t _ d a t a = 1 8 0 ; my $ t _ l a s t _ d a t a = 1000; # time when a l l data c o n n e c t i o n s h o u l d be up # time when t h e s i m u l a t i o n i s s t o p p e d

# t e m p o r a l working f o l d e r . . . my $ f o l d er _ t em p = " temp " ; mkdir $ f o l d er _ t em p ;

196

A.3. Perl

# select

filter

$ c h o i c e _ f i x = random movement ; #$choice_fix = hexa h o t s p o t ; #$choice_fix = hexa homogen ; #$choice_fix = c i r c l e random ; $choice_z #$ch o i ce_z $choice_x #$ c h o i c e _ x #$ c h o i c e _ x #$ c h o i c e _ x #$ c h o i c e _ x $choice_y #$ c h o i c e _ y = o nl y 4 ; = all ; = = = = = l o ad ; load_fine ; node d e n s i t y ; movement pause time ; movement s p e e d ;

= ratio ; = delay ;

# SET PARAMETER END # MAIN #s e t f i l t e r set_filter (); # s e l e c t f i l e s and c a l c u l a t e s t a t i s t i c f o r t h i s p o i n t file_filter (); # plot figure # o v e r w r i t e range i f needed $y_range =" 0.2 :1 " ; $x_range =" 1:4 " ; gnuplot ( ) ;

# sub f u n c t i o n sub s e t _ f i l t e r { p r i n t f ( " set f i l t e r . . . \ n" ) ; # s e t t h e f i l t e r t o s e l e c t t h e c o r r e c t . sim f i l e s # f i l t e r works on t h e name o f t h e . sim f i l e s # # f i l e name : # # [ d e s c r i p t i o n _ s h o r t] # r i [number_of_run ] # qt [ queue_type ] # q l [ q u e u e _ l e n gt h ] # dx[ dimension_x ] # dy [ d i m e n s i o n _ y ] # nn[number_node ] # sd [ s i m _ d u r a t i o n ] # sp [ s i m _ p r o g r e s s ] # pt [ pause_time ] # ms[maximum_speed ] # scp [ s c e n _ t y p e ] # s t [ s o u r c e _ t y p e ] # mc[ max_connection ] # ps [ p k t _ s i z e ]

197

A.3. Perl

# # # # # # # #

pr [ p k t _ r a t e ] s c [ s c h e d _ t y p e ] pn[aomdv_max_path ] . sim [ s i m u l a t i o n r e s u l t f i l e t y p e ] example : V010r i 9qt0q l 50dx2000dy2000nn80sd1000sp 100pt0ms0.0 . . . . . . scp 40s t c b rmc50ps 256pr 3.0s c 1pn 10. sim

# s e t f i x parameters # # V e r s i o n eg V002 # number_of_run # queue_type # q u e u e _ l e n gt h # dimension_x # dimension_y # simulation_duration # sim_progress # source_type # ending my my my my my my my $queue_type $queue_length $dimension_x $dimension_y $ s i m _ d ur at i o n $ s i m _ p r o g r es s $source_type

=" V001 . " =" r i . " ; =" qt 0 ."; =" q l 50 ."; =" dx 1500 ."; =" dy 1500 ."; =" sd 1000 ."; =" sp 10 ."; =" s t . c b r . " ; =" sim " ; = = = = = = = 0; 50; 2000; 2000; 1000; 100; cb r ;

i f ( $ c h o i c e _ f i x eq " hexa homogen " ) { # s c e n a r i o 30 $dimension_x $dimension_y = 2000; = 2000;

$fix_grep = " $version " . " . r i " . " . qt$queue_type " . " . ql$queue_length " . " .dx$dimension_x " . " . dy$dimension_y " . " . sd$ s i m _ d ur at i o n " . " . sp$ s i m _ p r o g r es s " . " . scp 30 " . " . s t . $ s o u r c e _ t y p e " . " . $simulation_result_type " ; $ f i x _ t i t l e = " hexagon homogen ( $dimension_x m x $dimension_y m) " ; $ f i x _ f i l e _ n a m e = " [ $ v e r s i o n dx$dimension_x dy$dimension_yhexahomogen ] " ; } e l s i f ( $ c h o i c e _ f i x eq " hexa ho t s p o t " ) { # s c e n a r i o 40 $dimension_x $dimension_y = 2000; = 2000;

$fix_grep = " $version " . " . r i " . " . qt$queue_type " . " . ql$queue_length " . " .dx$dimension_x " . " . dy$dimension_y " .

198

A.3. Perl

" . sd$ s i m _ d ur at i o n " . " . sp$ s i m _ p r o g r es s " . " . scp 40" . " . s t . $ s o u r c e _ t y p e " . " . $simulation_result_type " ; $ f i x _ t i t l e = " hexagon ho t s p o t $dimension_x m x $dimension_y m" ; $ f i x _ f i l e _ n a m e = " [ $ v e r s i o ndx$dimension_x dy$dimension_yhexaho t s p o t ] " ; } e l s i f ( $ c h o i c e _ f i x eq " c i r c l e random " ) { # s c e n a r i o 50 $dimension_x $dimension_y = 2000; = 2000;

$fix_grep = " $version " . " . r i " . " . qt$queue_type " . " . ql$queue_length " . " .dx$dimension_x " . " .dy$dimension_y " . " . sd$ s i m _ d ur at i o n " . " . sp$ s i m _ p r o g r es s " . " . scp 50 " . " . s t " . " . $source_type " . " . $simulation_result_type " ; $ f i x _ t i t l e = " c i r c l e random $dimension_x m x $dimension_y m" ; $ f i x _ f i l e _ n a m e = " [ $ v e r s i o ndx$dimension_x dy$dimension_yc i r c l e random ] " ; } e l s i f ( $ c h o i c e _ f i x eq " random movement " ) { # s c e n a r i o 00 # $dimension_x = 1000; $dimension_y = 1000; $fix_grep = " $version " . " . r i " . " . qt$queue_type " . " . ql$queue_length " . " .dx$dimension_x " . " .dy$dimension_y " . " . sd$ s i m _ d ur at i o n " . " . sp$ s i m _ p r o g r es s " . " . scp00" . " . s t " . " . $source_type " . " . $simulation_result_type " ; $ f i x _ t i t l e = " random movement $dimension_x m x $dimension_y m" ; $ f i x _ f i l e _ n a m e = " [ $ v e r s i o ndx$dimension_x dy$dimension_yc i r c l e random ] " ; } else { d i e " s et _ g r ep _ p ar am et er : Can t r e s o l v e \ $ c h o i c e _ f i x " ; } # # # # s e t Z parameter sched_type aomdv_max_path

=" s c . " ; =" pn . " ;

i f ( $ c h o i c e _ z eq " a l l " ) { # gr e p p a t t e r n f o r t h e z f i l t e r @z_dim_grep = ( " sc 0.pn 1 [ [ : punct : ] ] $ s i m u l a t i o n _ r e s u l t _ t y p e " ,

199

A.3. Perl

" sc 0.pn 1 0 [ [ : punct " sc 1.pn 1 0 [ [ : punct " sc 2.pn 1 0 [ [ : punct " sc 3.pn 1 0 [ [ : punct " sc 4.pn 1 0 [ [ : punct " sc 5.pn 1 0 [ [ : punct # l a b e l f o r t h e zdimension @z _ l ab el = ( "AODV 1 P " , "AOMDV 10 P " , " RR 10 P " , "WRR 10 P " , " S e l 10 P " , " RTT 10 P " , "NB 10 P " ) ;

:]] :]] :]] :]] :]] :]]

$simulation_result_type " $simulation_result_type " $simulation_result_type " $simulation_result_type " $simulation_result_type " $simulation_result_type "

, , , , , );

# part of the filename $ z _ f i l e_ nam e = " [ aodvaomdvr r wrrs e l r t t neighmp10] " ; } e l s i f ( $ c h o i c e _ z eq " o nl y 4 " ) { # gr e p p a t t e r n f o r t h e z f i l t e r @z_dim_grep = ( " sc 0.pn 1 [ [ : punct : ] ] $ s i m u l a t i o n _ r e s u l t _ t y p e " , " sc 0.pn 1 0 [ [ : punct : ] ] $ s i m u l a t i o n _ r e s u l t _ t y p e " " sc 1.pn 1 0 [ [ : punct : ] ] $ s i m u l a t i o n _ r e s u l t _ t y p e " " sc 2.pn 1 0 [ [ : punct : ] ] $ s i m u l a t i o n _ r e s u l t _ t y p e " " sc 3.pn 1 0 [ [ : punct : ] ] $ s i m u l a t i o n _ r e s u l t _ t y p e " # l a b e l f o r t h e zdimension @z _ l ab el = ( "AODV" , "AOMDV" , " RR " , "WRR" , " Sel " ) ; # part of the filename $ z _ f i l e_ nam e = " [ aodvaomdvr r wrrs e l ] " ; } e l s i f ( $ c h o i c e _ z eq " manual " ) { # DEBUG F I L T E R @z_dim_grep = ( " sc 3.pn15 " ) ; @z _ l ab el = ( " manual " ) ; $ z _ f i l e_ nam e = " [ manual ] " ; } else { d i e " s et _ g r ep _ p ar am et er : Can t r e s o l v e \ $ c h o i c e _ y " ; } # s e t X parameter # # number_node # pause_time # maximum_speed # connection # pkt_size # pkt_rate

, , , );

="nn . " ; =" pt 10 ."; ="ms 1 0 [ [ : punct : ] ] 0 . " ; ="mc20 ."; =" ps 256 ."; =" pr 1 [ [ : punct : ] ] 0 . " ;

# use t h i s v a r i a b l e s t o e a s i l y adapt f i l t e r my $nn = 5 0 ; # number o f nodes my $pt = 0 ; # pause time my $ms_H = 5 ; # s p e e d ( head ) my $ms_T = 0 ; # speed ( t a i l ) my $mc = 5 0 ; # maximum number o f c o n n e c t i o n s my $ps = 2 5 6 ; # pkt s i z e

200

A.3. Perl

my $pr_H = 1 ; my $pr_T =0;

# p k t r a t e ( head ) # pkt ra t e ( t a i l )

#use " \ [ " => due t o $a [ [ i s i n t e r p r e t a t i o n as a r r a y . . .

i f ( $ c h o i c e _ x eq " node d e n s i t y " ) { @x_dim_grep = ( " nn30.pt$pt .ms$ms_H \ [ \ [ : punct : ] ] $ms_T.mc$mc. ps$ps . " . " pr$pr_H \ [ \ [ : punct : ] ] $pr_T" , " nn50.pt$pt .ms$ms_H \ [ \ [ : punct : ] ] $ms_T.mc$mc. ps$ps . " . " pr$pr_H \ [ \ [ : punct : ] ] $pr_T" , " nn70. pt$pt .ms$ms_H \ [ \ [ : punct : ] ] $ms_T.mc$mc. ps$ps . " . " pr$pr_H \ [ \ [ : punct : ] ] $pr_T" , " nn100.pt$pt .ms$ms_H \ [ \ [ : punct : ] ] $ms_T.mc$mc. ps$ps . " . " pr$pr_H \ [ \ [ : punct : ] ] $pr_T" ) ; @x_data_point = ( 3 0 , 5 0 , 7 0 , 9 0 ) ; # a x i s i n gn u p l o t $x_axis = " numbers o f nodes " . " ( pt = $pt , ms = $ms_H . $ms_T , mc = $mc , pr = $pr_H . $pr_T , ps = $ps ) " ; $x_tics = " 3 0 , 5 0 , 70 , 9 0 " ; $x_range = " 0:90 " ; $x_title = " node d e n s i t y " ; $ x _ f i l e_ nam e = " [ nodes nnXXpt$ptms$ms_H . $ms_Tmc$mcps$pspr$pr_H . $pr_T ] " ; } e l s i f ( $ c h o i c e _ x eq " movement pause time " ) { @x_dim_grep = ( " nn$nn . pt 0.ms$ms_H \ [ \ [ : punct : ] ] $ms_T.mc$mc. ps$ps . " . " pr$pr_H \ [ \ [ : punct : ] ] $pr_T" , " nn$nn . pt 30.ms$ms_H \ [ \ [ : punct : ] ] $ms_T.mc$mc. ps$ps . pr" . " $pr_H \ [ \ [ : punct : ] ] $pr_T" , " nn$nn . pt 120.ms$ms_H \ [ \ [ : punct : ] ] $ms_T.mc$mc. ps$ps . pr" . " $pr_H \ [ \ [ : punct : ] ] $pr_T" , " nn$nn . pt 300.ms$ms_H \ [ \ [ : punct : ] ] $ms_T.mc$mc. ps$ps . pr" . " $pr_H \ [ \ [ : punct : ] ] $pr_T" , " nn$nn . pt 600.ms$ms_H \ [ \ [ : punct : ] ] $ms_T.mc$mc. ps$ps . pr" . " $pr_H \ [ \ [ : punct : ] ] $pr_T" , " nn$nn . pt 900.ms$ms_H \ [ \ [ : punct : ] ] $ms_T.mc$mc. ps$ps . pr" . " $pr_H \ [ \ [ : punct : ] ] $pr_T" ) ; @x_data_point = ( 0 , 3 0 , 6 0 , 1 2 0 , 6 0 0 , 9 0 0 ) ; # a x i s i n gn u p l o t $x_axis = " pause time [ s ] max speed $ms_H . $ms_T m/ s " . " ( nn = $nn , mc = $mc , ps = $ps , pr = $pr_H . $pr_T ) " ; $x_tics = " 0 ,30 ,60 ,120 ,600 ,900 " ; $x_range = " 0:1000 " ; $x_title = " movement " ; $ x _ f i l e_ nam e = " [ movement nn$nnptXXXms$ms_H . $ms_Tmc$mcps$pspr$pr_H . $pr_T ] " ; } e l s i f ( $ c h o i c e _ x eq " movement speed " ) { @x_dim_grep = ( " nn$nn . pt$pt .ms 1 [ [ : punct : ] ] 0 . mc$mc. ps$ps . " .

201

A.3. Perl

" pr$pr_H \ [ \ [ : punct : ] ] $pr_T" , " nn$nn . pt$pt .ms 2 [ [ : punct : ] ] 0 . mc$mc. ps$ps . " . " pr$pr_H \ [ \ [ : punct : ] ] $pr_T" , " nn$nn . pt$pt .ms 3 [ [ : punct : ] ] 0 . mc$mc. ps$ps . " . " pr$pr_H \ [ \ [ : punct : ] ] $pr_T" , " nn$nn . pt$pt .ms 4 [ [ : punct : ] ] 0 . mc$mc. ps$ps . " . " pr$pr_H \ [ \ [ : punct : ] ] $pr_T" , " nn$nn . pt$pt .ms 5 [ [ : punct : ] ] 0 . mc$mc. ps$ps . " . " pr$pr_H \ [ \ [ : punct : ] ] $pr_T" , " nn$nn . pt$pt .ms 6 [ [ : punct : ] ] 0 . mc$mc. ps$ps . " . " pr$pr_H \ [ \ [ : punct : ] ] $pr_T" , " nn$nn . pt$pt .ms 7 [ [ : punct : ] ] 0 . mc$mc. ps$ps . " . " pr$pr_H \ [ \ [ : punct : ] ] $pr_T" , " nn$nn . pt$pt .ms 8 [ [ : punct : ] ] 0 . mc$mc. ps$ps . " . " pr$pr_H \ [ \ [ : punct : ] ] $pr_T" , " nn$nn . pt$pt .ms 9 [ [ : punct : ] ] 0 . mc$mc. ps$ps . " . " pr$pr_H \ [ \ [ : punct : ] ] $pr_T" , " nn$nn . pt$pt .ms 9 [ [ : punct : ] ] 0 . mc$mc. ps$ps . " . " pr$pr_H \ [ \ [ : punct : ] ] $pr_T" ) ; @x_data_point = ( 1 , 2 , 3 , 4 , 5 , 6 , 7 , 8 , 9 , 1 0 ) ; # a x i s i n gn u p l o t $x_axis = "max speed [m/ s ] " . " ( pt = $pt , nn = $nn , mc = $mc , ps = $ps , pr = $pr_H . $pr_T ) " ; $x_tics = " 0 ,2 ,4 ,6 ,8 ,10 " ; $x_range = " 0:10 " ; $x_title = " movement " ; $ x _ f i l e_ nam e = " [ movement nn$nnptXXXms$ms_H . $ms_Tmc$mcps$pspr$pr_H . $pr_T ] " ; } e l s i f ( $ c h o i c e _ x eq " l o ad " ) { @x_dim_grep = ( " nn$nn . pt$pt .ms$ms_H \ [ \ [ : punct : ] ] $ms_T.mc$mc. " . " ps$ps . pr 1 [ [ : punct :]]0 " , " nn$nn . pt$pt .ms$ms_H \ [ \ [ : punct : ] ] $ms_T.mc$mc. " . " ps$ps . pr 1 [ [ : punct : ] ] 5 " , " nn$nn . pt$pt .ms$ms_H \ [ \ [ : punct : ] ] $ms_T.mc$mc. " . " ps$ps . pr 2 [ [ : punct :]]0 " , " nn$nn . pt$pt .ms$ms_H \ [ \ [ : punct : ] ] $ms_T.mc$mc. " . " ps$ps . pr 2 [ [ : punct : ] ] 5 " , " nn$nn . pt$pt .ms$ms_H \ [ \ [ : punct : ] ] $ms_T.mc$mc. " . " ps$ps . pr 3 [ [ : punct :]]0 " , " nn$nn . pt$pt .ms$ms_H \ [ \ [ : punct : ] ] $ms_T.mc$mc. " . " ps$ps . pr 3 [ [ : punct : ] ] 5 " , " nn$nn . pt$pt .ms$ms_H \ [ \ [ : punct : ] ] $ms_T.mc$mc. " . " ps$ps . pr 4 [ [ : punct :]]0 " , " nn$nn . pt$pt .ms$ms_H \ [ \ [ : punct : ] ] $ms_T.mc$mc. " . " ps$ps . pr 4 [ [ : punct : ] ] 5 " ,

202

A.3. Perl

" nn$nn . pt$pt .ms$ms_H \ [ \ [ : punct : ] ] $ms_T.mc$mc. " . " ps$ps . pr 5 [ [ : punct :]]0 " , " nn$nn . pt$pt .ms$ms_H \ [ \ [ : punct : ] ] $ms_T.mc$mc. " . " ps$ps . pr 5 [ [ : punct : ] ] 5 " , " nn$nn . pt$pt .ms$ms_H \ [ \ [ : punct : ] ] $ms_T.mc$mc. " . " ps$ps . pr 6 [ [ : punct :]]0 " , " nn$nn . pt$pt .ms$ms_H \ [ \ [ : punct : ] ] $ms_T.mc$mc. " . " ps$ps . pr 6 [ [ : punct : ] ] 5 " , " nn$nn . pt$pt .ms$ms_H \ [ \ [ : punct : ] ] $ms_T.mc$mc. " . " ps$ps . pr 7 [ [ : punct :]]0 " , " nn$nn . pt$pt .ms$ms_H \ [ \ [ : punct : ] ] $ms_T.mc$mc. " . " ps$ps . pr 8 [ [ : punct :]]0 " ); @x_data_point = ( 1 , 1 . 5 , 2 , 2 . 5 , 3 , 3 . 5 , 4 , 4 . 5 , 5 , 5 . 5 , 6 , 6 . 5 , 7 , 8 ) ; # a x i s i n gn u p l o t $x_axis = " p acket r a t e [ p a c k e t s / s ] " . " ( max con = $mc ; ps = $ps ; nn = $nn ; pt = $pt ; ms = $ms_H . $pt ) " ; $x_tics = " 0 ,1 ,2 ,3 ,4 ,5 ,6 ,7 ,8 " ; $x_range = " 0:10 " ; $x_title = " l o ad " ; $ x _ f i l e_ nam e = " [ load nn$nnpt$ptms$ms_H . $ms_Tmc$mcps$psprX . 0 ] " ; } e l s i f ( $ c h o i c e _ x eq " l o a d _ f i n e " ) { @x_dim_grep = ( " nn$nn . pt$pt .ms$ms_H \ [ \ [ : punct : ] ] $ms_T.mc$mc. " . " ps$ps . pr 1 [ [ : punct :]]0 " , " nn$nn . pt$pt .ms$ms_H \ [ \ [ : punct : ] ] $ms_T.mc$mc. " . " ps$ps . pr 1 [ [ : punct : ] ] 2 5 " , " nn$nn . pt$pt .ms$ms_H \ [ \ [ : punct : ] ] $ms_T.mc$mc. " . " ps$ps . pr 1 [ [ : punct : ] ] 5 " , " nn$nn . pt$pt .ms$ms_H \ [ \ [ : punct : ] ] $ms_T.mc$mc. " . " ps$ps . pr 1 [ [ : punct : ] ] 7 5 " , " nn$nn . pt$pt .ms$ms_H \ [ \ [ : punct : ] ] $ms_T.mc$mc. " . " ps$ps . pr 2 [ [ : punct :]]0 " , " nn$nn . pt$pt .ms$ms_H \ [ \ [ : punct : ] ] $ms_T.mc$mc. " . " ps$ps . pr 2 [ [ : punct : ] ] 2 5 " , " nn$nn . pt$pt .ms$ms_H \ [ \ [ : punct : ] ] $ms_T.mc$mc. " . " ps$ps . pr 2 [ [ : punct : ] ] 5 " , " nn$nn . pt$pt .ms$ms_H \ [ \ [ : punct : ] ] $ms_T.mc$mc. " . " ps$ps . pr 2 [ [ : punct : ] ] 7 5 " , " nn$nn . pt$pt .ms$ms_H \ [ \ [ : punct : ] ] $ms_T.mc$mc. " . " ps$ps . pr 3 [ [ : punct :]]0 " , " nn$nn . pt$pt .ms$ms_H \ [ \ [ : punct : ] ] $ms_T.mc$mc. " . " ps$ps . pr 3 [ [ : punct : ] ] 2 5 " , " nn$nn . pt$pt .ms$ms_H \ [ \ [ : punct : ] ] $ms_T.mc$mc. " . " ps$ps . pr 3 [ [ : punct : ] ] 5 " , " nn$nn . pt$pt .ms$ms_H \ [ \ [ : punct : ] ] $ms_T.mc$mc. " . " ps$ps . pr 3 [ [ : punct : ] ] 7 5 " ,

203

A.3. Perl

" nn$nn . pt$pt .ms$ms_H \ [ \ [ : punct : ] ] $ms_T.mc$mc. " . " ps$ps . pr 4 [ [ : punct :]]0 " ); @x_data_point = ( 1 , 1 . 2 5 , 1 . 5 , 1 . 7 5 , 2 , 2 . 2 5 , 2 . 5 , 2 . 7 5 , 3 . 0 , 3 . 2 5 , 3 . 5 , 3 . 7 5 , 4 . 0 ) ; # a x i s i n gn u p l o t $x_axis = " p acket r a t e [ p a c k e t s / s ] " . " ( max con = $mc ; ps = $ps ; nn = $nn ; pt = $pt ; ms = $ms_H . $pt ) " ; $x_tics = " 0 ,1 ,2 ,3 ,4 " ; $x_range = " 0:4 " ; $x_title = " l o ad " ; $ x _ f i l e_ nam e = " [ load nn$nnpt$ptms$ms_H . $ms_Tmc$mcps$psprX . 0 ] " ; } e l s i f ( $ c h o i c e _ x eq " manual " ) { d i e " manual not s e t . . . " ; } else { d i e " s et _ g r ep _ p ar am et er : Can t r e s o l v e \ $ c h o i c e _ x " ; }

# s e t Y parameter # i f ( $ c h o i c e _ y eq " r a t i o " ) { $y_axis = " d e l i v e r y r a t i o [ data p kt r e c e i v e d / data p kt s ent ] " ; $y_tics = " 0 ,0.1 ,0.2 ,0.3 ,0.4 ,0.5 ,0.6 ,0.7 ,0.8 ,0.9 ,1 " ; $y_range = " 0:1 " ; $y_title = " Delivery ratio " ; $ y _ f i l e_ nam e = " r a t i o " ; $stat_type = " delivery_ratio_mean " ; } e l s i f ( $ c h o i c e _ y eq " d e l a y " ) { $y_axis = " end to end d e l a y [ s ] " ; $y_tics = "0" ; $y_range = " 0:0.5 " ; $y_title = " End to end d e l a y " ; $ y _ f i l e_ nam e = " d e l a y " ; $ s t a t _ t y p e = " pkt_delay_mean " ; } else { d i e " s et _ g r ep _ p ar am et er : Can t r e s o l v e \ $ c h o i c e _ y " ; }

# DEBUG OUTPUT : i f ( $DEBUG= = 1 ) { p r i n t f ( " F I X : \ t %s \ nZ : \ t%s \ nX : \ t%s \ nZ : \ t%s \ n " , $fix_grep , $z_dim_grep [ 0 ] , $x_dim_grep [ 0 ] , $stat_type ) ; } }

sub f i l e _ f i l t e r { # T h i s f u n c t i o n s e a r c h f o r a l l d a t a p o i n t s t h e c o r r e s p o n d i n g sim f i l e s and

204

A.3. Perl

# c a l l and s a v e t h e s t a t i s t i c v a l u e f o r t h i s p o i n t i n t h e g l o b a l s t a t i s t i c c o n t a i n e r # # # # # # # # # # 1 . l i s t a l l f i l e s of the s i m u l a ti on r e s u l t f o l d e r 2 . perform F i x F i l t e r 3 . perform ZF i l t e r 4 . perform XF i l t e r 5 . perform YF i l t e r 6 . s a v e t h e s e l e c t e d sim f i l e s i n a g l o b a l f i l e c o n t a i n e r 7 . c a l l s t a t i s t i c ( ) > c a l c u l a t e s t h e s t a t i s t i c f o r t h i s p o i n t ( use t h e g l o b a l f i l e c o n t a i n e r ) 8 . save t h i s value i n the gl o b a l s t a t i s t i c c o n t a i n e r 9 . r e p e a t t h i s f o r a l l data p o i n t s

# loop v a r i a b l e s my $z_dim_index = 0 ; my $x_dim_index = 0 ; my @y ;

#l o o p v a r i a b l e i n z dim #l o o p v a r i a b l e i n x dim #l o o p s t a t i s t i c v a r i a b l e . . . \ n" ;

print " calculate st a t i st i c

# ge t a l l p o s s i b l e . P f i l e s and s a v e l i s t i n $ f o l d e r _ t e m p / l s _ a l l p r i n t rm f $ f o l d er _ t em p / l s _ a l l ; p r i n t l s $ s i m u l a t i o n _ r e s u l t s > $ f o l d er _ t em p / l s _ a l l ; # FIX F i l t e r p r i n t rm f $ f o l d er _ t em p / l i s t _ f i x ;

#remove e x i s t i n g f i l e

p r i n t ( " F I X F i l t e r : " , grep c $ f i x _ g r e p $ f o l d er _ t em p / l s _ a l l , " \ n " ) ; p r i n t grep $ f i x _ g r e p $ f o l d er _ t em p / l s _ a l l > $ f o l d er _ t em p / l i s t _ f i x ;

# ZF i l t e r f o r ( $z_dim_index = 0 ; $z_dim_index < s c a l a r ( @z_dim_grep ) ; $z_dim_index ++) { p r i n t rm f $ f o l d er _ t em p / l i s t _ z ; #remove e x i s t i n g f i l e p r i n t ( " \ t Z F i l t e r : " , grep c $z_dim_grep [ $z_dim_index ] $ f o l d er _ t em p / l i s t _ f i x , " \ t \ t \ t \ t ( $z_dim_grep [ $z_dim_index ] ) \ n " ) ; p r i n t grep $z_dim_grep [ $z_dim_index ] $ f o l d er _ t em p / l i s t _ f i x > $ f o l d er _ t em p / l i s t _ z ; f o r ( $x_dim_index= 0 ; $x_dim_index < s c a l a r ( @x_dim_grep ) ; $x_dim_index ++) { # XF i l t e r @file_to_stat = ( ) ; print ( " \ t \ t X F i l t e r : " , grep c $x_dim_grep [ $x_dim_index ] $ f o l d er _ t em p / l i s t _ z " \ t \ t \ t \ t ( $x_dim_grep [ $x_dim_index ] ) \ n " ) ;

@ f i l e _ t o _ s t a t = grep $x_dim_grep [ $x_dim_index ] $ f o l d er _ t em p / l i s t _ z

# C a l c u l a t e S t a t i s t i c over s e l e c t e d f i l e s i f ( s c a l a r ( @ f i l e _ t o _ s t a t )== 0) { p r i n t " \ t \ t \ t no f i l e s s e l e c t e d , s e t v al ue to 1 \ n " ; $ s t a t i s t i c _ c o n t a i n e r [ $z_dim_index ] [ $x_dim_index ]= [ ( 1 , 0 ) ] ; } else { # c a l c u l a t e s t a t i s t i c of the s e l e c t e d . P f i l e s

205

A.3. Perl

$ s t a t i s t i c _ c o n t a i n e r [ $z_dim_index ] [ $x_dim_index ] = [ s t a t i s t i c ( ) ] ; } } } } # c a l c s t a t over given f i l e _ t o _ s t a t _ a r r a y sub s t a t i s t i c { # r e a d t h e s i m u l a t i o n r e s u l t f i l e s and c a l c u l a t e t h e s t a t i s t i c # # F i l e parser , handler my $ f i l e _ i n d e x = 0 ; my @l i nes ; my $ l i n e ; my @elements ; # number o f nodes my $number_of_nodes_ total = 0 ; my $number_of_nodes_avg = 0 ;

# avg o v e r run

# data d e l i v e r y r a t i o ( r e c e i v e d / t r a n s m i t t e d ) my $ d a t a _ d e l i v e r y _ r a t i o _ l o o p = 0 ; my $ d a t a _ d e l i v e r y _ r a t i o _ a v g = 0 ; # avg o v e r d i f f e r e n t r u n s my $ d a t a _ d e l i v e r y _ r a t i o _ v a r = 0 ; # var over d i f f e r e n t runs # end t o end p k t d e l a y my $ end _ t o _ end _ p kt _ d el ay _ l o o p = 0 ; my $ end _ t o _ end _ p kt _ d el ay _ av g = 0 ; # avg o v e r d i f f e r e n t r u n s my $ end _ t o _ end _ p kt _ d el ay _ v a r = 0 ; # v a r o v e r d i f f e r e n t r u n s # Check i f s i m u l a t i o n r e s u l t f i l e # ( CORE BUG CHECK ) my $ num b er _ o f _ g o o d _ f i l es = 0 ; my $ d a t a _ p k t _ f i r s t _ t i m e = 0 ; my $ d a t a _ p k t _ l a s t _ t i m e = 0 ; my $ l as t _ t i m e_ s t am p = 0 ; i s compled

#r e t u r n y v a l u e ( s t a t i s t i c ) my @y ; # [ 1 ] = mean [ 2 ] = v a r

# # s e t loop v a r i a b l e s to zero $ d a t a _ d e l i v e r y _ r a t i o _ lo o p = 0; $ end _ t o _ end _ p kt _ d el ay _ l o o p = 0 ; $ num b er _ o f _ g o o d _ f i l es = 0 ; f o r ( $ f i l e _ i n d e x = 0 ; $ f i l e _ i n d e x < s c a l a r ( @ f i l e _ t o _ s t a t ) ; $ f i l e _ i n d e x ++) { $dat a_pkt _fir s t _t ime = 0; $data_pkt_last_time = 0; $ l as t _ t i m e_ s t am p = 0 ; open ( SI M_ F I L E , " < $ s i m u l a t i o n _ r e s u l t s / $ f i l e _ t o _ s t a t [ $ f i l e _ i n d e x ] " ) # open f i l e o r d i e " Couldn t open $ f i l e _ t o _ s t a t [ $ f i l e _ i n d e x ] f o r r ead i ng : $ ! \ n " ; ( @l i nes ) = < SI M_ F I L E > ; f o r e a c h $ l i n e ( @l i nes ) { # s p l i t l i n e i n elements

206

A.3. Perl

@elements = s p l i t ( / / , $ l i n e ) ; if { ( ( $elements [ 0 ] =~ m/ ( 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 ) / ) && ( s c a l a r ( @elements ) > 3 ) ) # number o f nodes $number_of_nod es_ total + + ; } i f ( $elements [ 0 ] =~ / RATIO / ) { # d e l i v e r e d data $ d a t a _ d e l i v e r y _ r a t i o _ l o o p += $elements [ 1 ] ; } i f ( $elements [ 0 ] =~ /AVRG TOTAL d e l a y o f a data p acket / ) { # end t o end p k t d e l a y $ end _ t o _ end _ p kt _ d el ay _ l o o p += $elements [ 1 ] ; } i f ( $elements [ 0 ] =~ / f i r s t data with i d / && s c a l a r ( @elements ) < 8 ) { # f i r s t data p k t s e n t $ d a t a _ p k t _ f i r s t _ t i m e = $elements [ 3 ] ; } i f ( $elements [ 0 ] =~ / l a s t data with i d / && s c a l a r ( @elements ) < 8 ) { # l a s t data p k t s e n t $ d a t a _ p k t _ l a s t _ t i m e = $elements [ 3 ] ; } } c l o s e ( SI M_ F I L E ) o r d i e " Couldn t c l o s e $ f i l e _ t o _ s t a t [ $ f i l e _ i n d e x ] \ n " ; #c h e c k i f s i m u l a t i o n run u n t i l t h e end i f ( ( $data_pkt_first_time < $t _fir s t _dat a + 10) && ( $ d a t a _ p k t _ l a s t _ t i m e > $ t _ l a s t _ d a t a 10 ) ) { $ num b er _ o f _ g o o d _ f i l es + + ; } else { p r i n t " F i r s t data p kt s ent at : $ d a t a _ p k t _ f i r s t _ t i m e \ n " ; p r i n t " F i r s t data p kt s ent at : $ d a t a _ p k t _ l a s t _ t i m e \ n " ; p r i n t " F i l e Name : $ f i l e _ t o _ s t a t [ $ f i l e _ i n d e x ] \ n " ; } }

# c h e c k i f a l l s i m u l a t i o n f i l e s were OK i f ( $ num b er _ o f _ g o o d _ f i l es ! = $ f i l e _ i n d e x ) { d i e " Some . sim f i l e s ar e c o r r u p t ! ! $ ! \ n " ; }

# c a l c u l a t e a v gs : $number_of_nodes_avg $data_delivery_ratio_avg $ end _ t o _ end _ p kt _ d el ay _ av g

= $number_of_no des_total / s c a l a r ( @ f i l e _ t o _ s t a t ) ; = $data_delivery_ratio_loop/ scalar ( @file_to_stat ) ; = $ end _ t o _ end _ p kt _ d el ay _ l o o p / s c a l a r ( @ f i l e _ t o _ s t a t ) ;

# c o l l e c t data f o r v a r # s e t loop v a r i a b l e s to zero $ d a t a _ d e l i v e r y _ r a t i o _l o o p = 0; $ end _ t o _ end _ p kt _ d el ay _ l o o p = 0 ;

207

A.3. Perl

f o r ( $ f i l e _ i n d e x = 0 ; $ f i l e _ i n d e x < s c a l a r ( @ f i l e _ t o _ s t a t ) ; $ f i l e _ i n d e x ++) { open ( SI M_ F I L E , " < $ s i m u l a t i o n _ r e s u l t s / $ f i l e _ t o _ s t a t [ $ f i l e _ i n d e x ] " ) # open f i l e o r d i e " Couldn t open $ f i l e _ t o _ s t a t [ $ f i l e _ i n d e x ] f o r r ead i ng : $ ! \ n " ; ( @l i nes ) = < SI M_ F I L E > ; f o r e a c h $ l i n e ( @l i nes ) { # s p l i t l i n e i n elements @elements = s p l i t ( / / , $ l i n e ) ; i f ( $elements [ 0 ] =~ / RATIO / ) { # d e l i v e r e d data v a r i a n c e $ d a t a _ d e l i v e r y _ r a t i o _ l o o p += ( $elements [ 1 ] $ d a t a _ d e l i v e r y _ r a t i o _ a v g ) 2 ; } i f ( $elements [ 0 ] =~ /AVRG TOTAL d e l a y o f a data p kt / ) { # end t o end p k t d e l a y $ end _ t o _ end _ p kt _ d el ay _ l o o p += ( $elements [ 1 ] $ end _ t o _ end _ p kt _ d el ay _ av g ) 2 ; } } c l o s e ( SI M_ F I L E ) o r d i e " Couldn t c l o s e $ f i l e _ t o _ s t a t [ $ f i l e _ i n d e x ] \ n " ; }

# c a l c u l a t e var $data_delivery_ratio_var = $data_delivery_ratio_loop / scalar ( @file_to_stat ) ; $ end _ t o _ end _ p kt _ d el ay _ v ar = $ end _ t o _ end _ p kt _ d el ay _ l o o p / s c a l a r ( @ f i l e _ t o _ s t a t ) ; #DEBUG i f ( $DEBUG == 1 ) { #files p r i n t ( " Number o f runs : \ t " , s c a l a r ( @ f i l e _ t o _ s t a t ) , " \ n " ) ; p r i n t ( " Number o f good f i l e s : \ t \ t $ num b er _ o f _ g o o d _ f i l e s \ n " ) ; p r i n t ( " Used f i l e s : \ n @ f i l e _ t o _ s t a t \ n " ) ; #va l u es p r i n t ( " Average number o f nodes : \ t \ t$number_of_nodes_avg \ n " ) ; p r i n t ( " Data d e l i v e r y r a t i o i n average : \ t \ t \ t $ d a t a _ d e l i v e r y _ r a t i o _ a v g \ n " ) ; p r i n t ( " Data d e l i v e r y r a t i o v a r i a n c e : \ t \ t $ d a t a _ d e l i v e r y _ r a t i o _ v a r \ n " ) ; p r i n t ( " End to end p kt d e l a y i n average : \ t \ t $ end _ t o _ end _ p kt _ d el ay _ av g \ n " ) ; p r i n t ( " End to end p kt d e l a y v a r i a n c e : \ t \ t $ end _ t o _ end _ p kt _ d el ay _ v ar \ n " ) ; } # s e l e c t return value i f ( $ s t a t _ t y p e eq " d e l i v e r y _ r a t i o _ m e a n " ) { # g i v e back d e l i v e r y r a t i o @y = ( $ d a t a _ d e l i v e r y _ r a t i o _ a v g , $ d a t a _ d e l i v e r y _ r a t i o _ v a r , s c a l a r ( @ f i l e _ t o _ s t a t ) ) ; } e l s i f ( $ s t a t _ t y p e eq " pkt_delay_mean " ) { # g i v e back end t o end p k t d e l a y @y = ( $end_to_end_p kt_delay_ avg , $ end _ t o _ end _ p kt _ d el ay _ v ar , s c a l a r ( @ f i l e _ t o _ s t a t ) ) ; } else { d i e " sub : get_standard_mean : $ s t a t _ t y p e i s not implemented \ n " ; } r e t u r n ( @y ) ;

208

A.3. Perl

} # Gnuplot sub gnuplot { # write a single plot my $ g n u _ d a t a _ f i l e = " g n u _ d a t a _ s i n g l e p l o t . tmp " ; my $ g n u _ h e a d e r _ f i l e = " g n u _ h e a d e r _ s i n g l e p l o t . tmp " ; my $ g n u _ o u t p u t _ f i l e = " $ f i x _ f i l e _ n a m e $ z _ f i l e_ nam e$x_file_nam e $ y _ f i l e_ nam e . eps " ; # w r i t e data f i l e # p r i n t " g ener at e gnu data f i l e . . . \n " ;

open ( GNUPLOT_DATA , " > $ f o l d er _ t em p / $ g n u _ d a t a _ f i l e " ) o r d i e " can t w r i t e $ f o l d er _ t em p / $ g n u _ d a t a _ f i l e f o r (my $ i = 0 ; $ i < s c a l a r ( @x_dim_grep ) ; $ i ++) { p r i n t GNUPLOT_DATA " $ x _ d at a_ p o i nt [ $ i ] \ t " ;

file " ;

f o r ( my $ j = 0 ; $ j < s c a l a r ( @z_dim_grep ) ; $ j ++) { p r i n t f GNUPLOT_DATA ( "0%f \ t " , $ s t a t i s t i c _ c o n t a i n e r [ $ j ] [ $ i ] [ 0 ] ) ; # mean p r i n t f GNUPLOT_DATA ( "0%f \ t " , s q r t ( $ s t a t i s t i c _ c o n t a i n e r [ $ j ] [ $ i ] [ 1 ] ) ) ; # s t a d p r i n t f GNUPLOT_DATA ( "0%f \ t " , $ s t a t i s t i c _ c o n t a i n e r [ $ j ] [ $ i ] [ 2 ] ) ; # samples } p r i n t GNUPLOT_DATA " \ n " ; } c l o s e ( GNUPLOT_DATA ) o r d i e " can t c l o s e $ f o l d er _ t em p / $ g n u _ d a t a _ f i l e # w r i t e header f i l e # p r i n t " g ener at e gnu header f i l e . . . \ n" ; file " ;

open ( GNUPLOT_HEADER , " > $ f o l d er _ t em p / $ g n u _ h e a d e r _ f i l e " ) o r d i e " can t w r i t e $ f o l d er _ t em p / $ g n u _ h e a d e r _ f i l e " ; p r i n t GNUPLOT_HEADER " # output f i l e t y p e : s e t term p o s t s c r i p t eps enhanced c o l o r # output f i l e s e t output \ " $ f o l d er _ t em p / $ g n u _ o u t p u t _ f i l e \ " # plot size set s i z e 0.8 ,0.8 # labels set t i t l e

\ " $ y _ t i t l e v e r s u s $ x _ t i t l e ( $ f i x _ t i t l e ) \ " f o n t \ " H e l v e t i c a Bold , 1 4 \ "

set x t i c s ( $x _t i cs ) set xlabel \" $x_axis \ " s e t xrange [ $x_range ] set y t i c s ( $y_tics ) set y l ab el \" $y_axis s e t yrange [ $y_range ] # p o s i t i o n o f the key s e t key l e f t bottom # s t y l e o f p o i n t s and l i n e s

\"

209

A.3. Perl

set p o i nt s i z e 1 "; # p l o t c o n s t r u c t p l o t command p r i n t GNUPLOT_HEADER " p l o t " ; f o r ( my $z_dim_index = 0 ; $z_dim_index < s c a l a r ( @z_dim_grep ) ; $z_dim_index ++) { #print l i n e p r i n t GNUPLOT_HEADER " \ " $ f o l d er _ t em p / $ g n u _ d a t a _ f i l e \ " us i ng 1 : " , 3 $z_dim_index +2 , " : " , 3 $z_dim_index + 3 , " t i t l e \ " $ z _ l a b e l [ $z_dim_index ] \ " with y e r r o r l i n e s l t $z_dim_index l i n e w i d t h 2 " ; i f ( ( $z_dim_index + 1 ) < s c a l a r ( @z_dim_grep ) ) {# n e x t data s e t p r i n t GNUPLOT_HEADER " , " ; } else {# l a s t data s e t p r i n t GNUPLOT_HEADER " \ n " ; } } c l o s e ( GNUPLOT_HEADER ) ; # make g r a p h i c p r i n t gnuplot $ f o l d er _ t em p / $ g nu_ hea d e r _ f i l e ; p r i n t gv $ f o l d er _ t em p / $ g n u _ o u t p u t _ f i l e }

Listing A.12: analysis_multiple_runs.pl

210

A.4. Gawk

A.4. Gawk
A.4.1. tr_to_val.awk
# # # # # # # # # # # # # # # # # { # preparations delete array ; # reading l i n e into array a r r a y [ " event " ] = $ 1 ; f o r ( i = 2 ; i <NF ; i ++) { i f ( i nd ex ( $ i , "" ) == 1 ) { array [ substr ( $i , 2 ) ] = $ ( i +1) } } # making c o n v e r s i o n i f ( a r r a y [ "Md" ] == i f ( a r r a y [ " Mt " ] == i f ( a r r a y [ " Po " ] == i f ( a r r a y [ " Po " ] == i f ( a r r a y [ " Pc " ] == i f ( a r r a y [ " Pc " ] == i f ( a r r a y [ " Pc " ] == i f ( a r r a y [ " Pc " ] == i f ( a r r a y [ " Pc " ] == i f ( a r r a y [ " Pc " ] == i f ( a r r a y [ "Nw" ] == i f ( a r r a y [ " Nl " ] == i f ( a r r a y [ " Nl " ] == i f ( a r r a y [ " I t " ] == i f ( a r r a y [ " I t " ] == R a i n e r Baumann , ETH Z u e r i c h 2004 Master T h e s i s awk c o n v e r t e r f o r ns2 t r a c e f i l e s from new format t o v a l format

[ scheduling s tar t ] Project : S e m e s t e r T h e s i s S S 06: E v a l u a t i o n o f s c h e d u l i n g methods o v e r m u l t i p a t h r o u t i n g i n w i r e l e s s m o b i l e Ad Hoc networks

A u t h o r s : R e gu l a Goenner , Dominik Schatzmann add PING add INFO PACKET f i x node 0 BUG [ s c h e d u l i n g end ]

" ffffffff " ) a r r a y [ "Md" ]= " f " ; " 800 " ) a r r a y [ "Mt " ]= " 8 " ; " REPLY " ) a r r a y [ " Po " ]= " REP " ; " REQUEST " ) a r r a y [ " Po " ]= " REQ " ; " REPLY " ) a r r a y [ " Pc " ]= " REP " ; " ERROR " ) a r r a y [ " Pc " ]= " E " ; " UNSOLICITED REPLY " ) a r r a y [ " Pc " ]= " E " ; " HELLO " ) a r r a y [ " Pc " ]= " HI " ; " PING " ) a r r a y [ " Pc " ]= " P I " ; " REQUEST " ) a r r a y [ " Pc " ]= " REQ " ; "" ) a r r a y [ "Nw" ]= " | " ; " AGT " ) a r r a y [ " Nl " ]= "AG" ; " RTR " ) a r r a y [ " Nl " ]= " R " ; " DSR " ) a r r a y [ " I t " ]= "D" ; " cb r " ) a r r a y [ " I t " ]= " C " ;

# added f o r AODVM # [ scheduling ]

# processing d i f fe r ent cases i f ( a r r a y [ " event " ] == "M" ) { { p r i n t f ( "%s \ n " , $0 ) } ; } else i f ( \ ( a r r a y [ " event " ] == " s " ) | | \ ( a r r a y [ " event " ] == " r " ) | | \ ( a r r a y [ " event " ] == " d " ) | | \ ( a r r a y [ " event " ] == " f " ) ) { { p r i n t f ( "%s %s %s %s %s %s %s %s " , \ a r r a y [ " event " ] ,

211

A.4. Gawk

array [ " t " ] , \ a r r a y [ " Hs " ] , \ a r r a y [ " Hd " ] , \ a r r a y [ " Nx " ] , \ a r r a y [ " Ny " ] , \ a r r a y [ " Nl " ] , \ a r r a y [ "Nw" ] ) }; # mac l a y e r e x t e n s i o n s { p r i n t f ( "%s %s %s %s " , \ a r r a y [ "Ma" ] , \ a r r a y [ "Md" ] , \ a r r a y [ "Ms" ] , \ a r r a y [ " Mt " ] ) }; i f ( array [ " Is " ]~ / . / ) { p r i n t f ( "%s %s %s %s %s %s %s " , \ array [ " Is " ] , \ array [ " Id " ] , \ array [ " I t " ] , \ array [ " I l " ] , \ array [ " I f " ] , \ array [ " I i " ] , \ array [ " Iv " ] ) }; i f ( a r r a y [ " P " ] == " d s r " ) { p r i n t f ( "%s %s %s %s %s %s>%s %s %s %s>%s " , \ a r r a y [ " Ph " ] , \ a r r a y [ " Pq " ] , \ a r r a y [ " Ps " ] , \ a r r a y [ " Pp " ] , \ a r r a y [ " Pn " ] , \ array [ " Pl " ] , \ a r r a y [ " Pe " ] , \ a r r a y [ "Pw" ] , \ a r r a y [ "Pm" ] , \ a r r a y [ " Pc " ] , \ a r r a y [ " Pb " ] ) };

i f ( a r r a y [ " P " ] == " mpdsr " ) { p r i n t f ( "%s %s %s %s %s %s>%s %s %s %s>%s " , \ a r r a y [ " Ph " ] , \ a r r a y [ " Pq " ] , \ a r r a y [ " Ps " ] , \ a r r a y [ " Pp " ] , \ a r r a y [ " Pn " ] , \ array [ " Pl " ] , \ a r r a y [ " Pe " ] , \ a r r a y [ "Pw" ] , \ a r r a y [ "Pm" ] , \ a r r a y [ " Pc " ] , \ a r r a y [ " Pb " ] ) }; i f ( a r r a y [ " P " ] == " aodv " ) { i f ( a r r a y [ " Pc " ] == " REQ " ) { p r i n t f ( "%s %s %s %s %s %s %s REQ " , \ a r r a y [ " Pt " ] , \ a r r a y [ " Ph " ] , \ a r r a y [ " Pb " ] , \ a r r a y [ " Pd " ] , \ a r r a y [ " Pds " ] , \

212

A.4. Gawk

a r r a y [ " Ps " ] , \ a r r a y [ " Ps s " ] ) } # [ s c h e d u l i n g ] added P I e l s e i f ( ( a r r a y [ " Pc " ] == " REP " ) | | ( a r r a y [ " Pc " ] == " E " ) | | \ ( a r r a y [ " Pc " ] == " HI " ) | | ( a r r a y [ " Pc " ] == " P I " ) ) { p r i n t f ( "%s %s %s %s %s %s " , \ a r r a y [ " Pt " ] , \ a r r a y [ " Ph " ] , \ a r r a y [ " Pd " ] , \ a r r a y [ " Pds " ] , \ array [ " Pl " ] , \ a r r a y [ " Pc " ] ) } else p r i n t f ( " Unexpected Pc \"% s \ " i n aodv event at l i n e %i \ n " , a r r a y [ " Pc " ] , NR ) } i f ( a r r a y [ " P " ] == " aodvm " ) { i f ( a r r a y [ " Pc " ] == " REQ " ) { p r i n t f ( "%s %s %s %s %s %s %s REQ " , \ a r r a y [ " Pt " ] , \ a r r a y [ " Ph " ] , \ a r r a y [ " Pb " ] , \ a r r a y [ " Pd " ] , \ a r r a y [ " Pds " ] , \ a r r a y [ " Ps " ] , \ a r r a y [ " Ps s " ] ) } e l s e i f ( ( a r r a y [ " Pc " ] == " REP " ) | | \ ( a r r a y [ " Pc " ] == " E " ) | | \ ( a r r a y [ " Pc " ] == " HI " ) ) { p r i n t f ( "%s %s %s %s %s %s " , \ a r r a y [ " Pt " ] , \ a r r a y [ " Ph " ] , \ a r r a y [ " Pd " ] , \ a r r a y [ " Pds " ] , \ array [ " Pl " ] , \ a r r a y [ " Pc " ] ) } else p r i n t f ( " Unexpected Pc \"% s \ " i n aodv event at l i n e %i \ n " , a r r a y [ " Pc " ] , NR ) } i f ( a r r a y [ " P " ] == " arp " ) { p r i n t f ( " P %s %s %s %s %s " , \ a r r a y [ " Po " ] , \ a r r a y [ " Pms " ] , \ a r r a y [ " Ps " ] , \ a r r a y [ "Pmd " ] , \ a r r a y [ " Pd " ] ) }; i f ( a r r a y [ " Pn " ] == " t cp " ) { p r i n t f ( "%s %s %s %s %s " , \ a r r a y [ " Pn " ] , \ a r r a y [ " Ps " ] , \ a r r a y [ " Pa " ] , \ a r r a y [ " Pf " ] , \ a r r a y [ " Po " ] ) }; i f ( a r r a y [ " Pn " ] == " cb r " ) { p r i n t f ( "%s %s %s " , \ array [ " Pi " ] , \ a r r a y [ " Pf " ] , \ a r r a y [ " Po " ] )

213

A.4. Gawk

}; i f ( a r r a y [ " P " ] == " imep " ) { p r i n t f ( "%s %s %s %s %s " , \ array [ " P " ] , \ a r r a y [ " Pa " ] , \ a r r a y [ " Ph " ] , \ a r r a y [ " Po " ] , \ array [ " Pl " ] ) }; i f ( a r r a y [ " P " ] == " t o r a " ) p r i n t f ( "P t o r a ; not j e t implemented " ) ; p r i n t f ( " \n " ) ; } e l s e i f ( a r r a y [ " event " ] == " i " ) { # [ s c h e d u l i n g ] i n f o p a c k e t , j u s t copy t h e i n f o r m a t i o n p r i n t f ( "%s \ n " , $0 ) } else { p r i n t f ( " Unexpected event \"% s \ " at b eg i nni ng o f l i n e %i \ n " , a r r a y [ " event " ] , NR ) ; } }

Listing A.13: tr_to_val.awk

214

A.4. Gawk

A.4.2. val_to_sim.awk
# # VAL_TO_SIM . AWK S C R I P T TO PARSE INFORMATION FROM . VAL TO . SIM # # P r o j e c t : S e m e s t e r T h e s i s S S 06: # E v a l u a t i o n o f s c h e d u l i n g methods o v e r # m u l t i p a t h r o u t i n g i n w i r e l e s s m o b i l e Ad Hoc networks # # A u t h o r s : R e gu l a Goenner , Dominik Schatzmann # # [ gawk S c r i p t ] # # Date : J u l y 2006 # # Input : val f i l e # # Output : s d t o u t o r t o a . sim f i l e , c o n t a i n s i n f o r m a t i o n o f t h e s i m u l a t i o n f o r each node # and , i f I n f o p a c k e t s a r e used , i n f o r m a t i o n about t h e r o u t i n g t a b l e # # based on an e x i s t i n g s c r i p t , unused v a r i a b l e s have not been v e r i f i e d # o r i g i n a l author : va l # changes t o t h e o r i g i n a l p a r t a r e marked with [ s c h e d u l i n g ] t a g s # ################ OLD and NEW #################################### # # AODV p a c k e t , $ 1 5 = AODV , send / r e c e i v e REPLY / ERROR / HI a c t i o n s # o r i g i n a l en try i n the t r a c e f i l e : # s t 3. 25 8 5 9 0 8 0 7 Hs 8 Hd 42 Ni 8 Nx 8 6 4 . 5 7 Ny 629.00 Nz 0.00 Ne 1.000000 Nl RTR # Nw Ma 0 Md 0 Ms 0 Mt 0 I s 8 . 2 5 5 I d 6 . 2 5 5 I t AODV I l 52 I f 0 I i 0 I v 30 # P aodv P t 0x4 Ph 0 Pd 8 Pds 2 P l 10.000000 Pc REPLY # # from t h e v a l f i l e # 1 2 3 4 5 6 7 8 9 10 1 1 12 13 14 # s 3. 25 8 5 9 0 8 0 7 8 42 864.57 629.00 R | 0 0 0 0 8.255 6.255 # t Hs Hd Nx Ny Nl Nw Ma Md Ms Mt I s I d # # 15 16 17 18 19 20 2 1 22 23 24 25 # AODV 52 0 0 30 0x4 0 8 2 10.000000 REP # I t I l I f I i I v P t Ph Pd Pds P l Pc ( = REP / HI / E ) # # "0 x%x %d %d %d %f %s " , # rp >r p _ t y p e , / / P t # rp >rp_hop_count , / / Ph # rp >r p _ d s t , / / Pd # rp >r p _ d s t _ s e q n o , / / Pds # rp > r p _ l i f e t i m e , / / P l # rp >r p _ t y p e == AODVTYPE_RREP ? " REP " : # ( rp >r p _ t y p e == AODVTYPE_RERR ? " E " : # " HI " ) ) ; / / Pc # # # CBR p a c k e t , $ 1 5 = C # o r i g i n a l en try i n the t r a c e f i l e : # s t 3. 229 4 20 0 5 6 Hs 6 Hd 2 Ni 6 Nx 5 2 . 1 8 Ny 1 2 6 . 6 9 Nz 0.00 Ne 1.000000 Nl # Nw Ma 0 Md 0 Ms 0 Mt 0 I s 6 . 2 I d 8 . 0 I t c b r I l 5 1 2 I f 0 I i 0 I v 32 # Pn c b r P i 0 P f 0 Po 0 # # from t h e v a l f i l e # 1 2 3 4 5 6 7 8 9 10 1 1 12 13 14 15 # s 3. 229 4 20 0 5 6 6 2 52.18 126.69 AG | 0 0 0 0 6.2 8.0 C # t Hs Hd Nx Ny Nl Nw Ma Md Ms Mt I s I d I r # # 17 1 8 1 9 20 2 1 22

AGT

16 512 I l

215

A.4. Gawk

# 0 0 32 # I f I i I v

0 0 0 P i P f Po

#/ ORIGINAL # "Pn c b r P i %d P f %d Po %d " , # rh >seqno_ , # ch>num_forwards ( ) , # ch>opt_num_forwards ( ) ) ; #/ # # # AODV p a c k e t , 1 5 = AODV , send / r e c i e v e REQUEST a c t i o n s # o r i g i n a l en try i n the t r a c e f i l e : # r t 3 . 2 3 0 4 1 2 3 7 6 Hs 3 1 Hd 2 Ni 3 1 Nx 9 5 . 9 8 Ny 2 1 1 . 9 7 Nz 0.00 Ne 1.000000 Nl # RTR Nw Ma 0 Md f f f f f f f f Ms 6 Mt 800 I s 6 . 2 5 5 I d 1 . 25 5 I t AODV I l 52 I f 0 # I i 0 I v 30 P aodv P t 0x2 Ph 0 Pb 1 Pd 8 Pds 0 P s 6 P s s 4 Pc REQUEST # # from t h e v a l f i l e # 1 2 3 4 5 6 7 8 9 10 11 12 13 14 # r 3.230412376 31 2 95.98 211.97 R | 0 f 6 8 6.255 1 . 25 5 # t Hs Hd Nx Ny Nl Nw Ma Md Ms Mt I s I d # # 15 16 17 18 19 20 2 1 22 23 24 25 26 27 # AODV 52 0 0 30 0x2 0 1 8 0 6 4 REQ # I t I l I f I i I v P t Ph Pb Pd Pds P s P s s Pc # # "0 x%x %d %d %d %d %d %d REQ " , # rq >r q _ t y p e , / / P t # rq >rq_hop_count , / / Ph # rq >r q _ b c a s t _ i d , / / Pb # rq >r q _ d s t , / / Pd # rq >r q _ d s t _ s e q n o , / / Pds # rq > r q _ s r c , / / P s # rq >r q _ s r c _ s e q n o ) ; / / P s s # # # [ s c h e d u l i n g ] s t a r t # # INFO p a c k e t : dump t h e p a t h s o f t h e r o u t i n g t a b l e # o r i g i n a l e n t r y i n t h e t r a c e f i l e ( t h i s i s not changed i n t h e v a l ) : # 1 2 3 4 5 6 7 8 9 10 1 1 1 2 1 3 1 4 1 5 1 6 1 7 1 8 19 # i t 1 6 2 . 7 7 7 5 9 1 Hs 68 Hd 27 I a 1 I c 1 I n 47 I l 68 I h 1 I r 1000.000000 # # Hs s o u r c e o f t h e path # Hd d e s t i n a t i o n o f t h e path # I a a c t i o n ( add = 1 , remove = 1 path ) # Ic t o t a l number o f p a t h s i n r o u t i n g t a b l e # I n n e x t hop # Il l a s t hop # I h hop count along # Ir r t t along t h i s path # # # [ s c h e d u l i n g ] end BEGIN { i f (M_N! = 0) MAX_NODES = M_N; # column numbers Line Time

= 0; = 2;

# the hole l i n e # t h e time column , was 3

216

A.4. Gawk

# Node i n f o r m a t i o n ThisNode = 3; NextNode = 4; ProtocolStack = 7; Xcoord = 5; Ycoord = 6;

# # # # #

Hs Hd Nl X coordinate Y c o o r d i n a t e o f a node

# packet information # common f o r a l l p a c k e t t y p e s ReasonWhyDropped = 8 ; # DestMAC = 10; # IP_SourceAddress = 1 3 ; # IP_DestAddress = 1 4 ; # DataOrRouting = 15; # PacketSize = 16; # I P_ U ni q ueI d = 18; #

Nw MAC a d d r e s s o f t h e d e s t i n a t i o n Is Id P d s r o r Pn c b r o r AODV I l , The s i z e o f a p a c k e t i n b y t e s Ii

# protocol s p e c i f i c information # CBR CBR_TimesFw = 21; # P f o n l y when Pn c b r ( 1 5 = C i n new ) , was 49 CBR_SequenceNumber = 2 0 ; # P i , o n l y with Pn c b r ( 1 5 = C i n new ) , was 47 # DSR NodesTraversed RouteReqFlag RouteRepFlag RouteErrFlag = = = = 20; 21; 23; 26; # # # # Ph == == == only 1 if 1 if 1 if when it s it s it s P d s r ( 1 5 = a DSR r o u t e a DSR r o u t e a DSR r o u t e D i n new ) , was 55 request packet rep l y packet e r r o r packet

# AODV AODV_PktType = 20; # 0x2 o r 0x4 AODV_HopCount = 21; # number o f hops t r a v e r s e d # REQUEST s / r AODV_BrdcastID = 2 2 ; AODV_ReqDest = 23; AODV_ReqDestSeqNum = 2 4 ; AODV_ReqSrc = 25; AODV_ReqSrcSeqNum = 2 6 ; AODV_REQ = 27; # REPLY / HELLO / ERROR AODV_RepDest = 22; AODV_ErrDest = 22; AODV_RepDestSeqNum = 2 3 ; AODV_RepLifeTime = 2 4 ; AODV_REP = 25; AODV_ERR = 25; # ATTENTION : AODV ERROR i s a BROADCAST p a c k e t ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! # [ s c h e d u l i n g ] s t a r t #HELLO / PING AODV_PI = 24; AODV_HI = 25; # i n f o p a c k e t new path_time = path_src = p at h_ d s t = path_action = path_number_total path_hop_next = p at h_ ho p _ l as t = path_hop_count = path_rtt = maxPathLength 3; 5; 7; 9; = 11; 13; 15; 17; 19;

= 10;

217

A.4. Gawk

timeInterval = 1; # [ s c h e d u l i n g ] end # ARP p a c k e t AR P_ i f Ar p ARP_PacketType = 13; = 14;

# sampling i n t e r v a l

# variables # Compute v a r i a b l e s accumulateFwValue = 0 ; numFwValue = 0; ## NEW arpREPdrops arpREQdrops arpDrops

= 0; = 0; = 0; # remember t h e h i g h e s t unique i d f o r data p a c k e t s # remember t h e l o w e s t unique i d f o r data p a c k e t s # node [ node_id , what ] an a r r a y t o s t o r e a l l t h e # e v e n t s i n a node

highest_packet_id = 0; l o w e s t _ p a c k e t _ i d = 100000; node [ 0 , 0 ] = 0;

# [ s c h e d u l i n g ] s t a r t #r o u t i n g t a b l e r t a b l e [0 ,0 ,0 ,0 ,0] = 0; r t a b l e _ s _ t [0 , 0 , 0 , 0] = 0; dat a_s r c_des t _t able [0 , 0] = 0; r t a b l e _ s r c [0 , 0 , 0] = 0;

# s a v e a l l r o u t i n g i n f o s o f t h e INFO PATH PACKET # i n t h i s t a b l e [ s r c , d e s t , pathnumber | i n f o , HASH ] #s a v e a l l p a t h s t h a t were found d u r i n g t h e s i m u l a t i o n # save a l l dataflows i n t h i s t a b l e # s a v e t h e number o f path t h a t t h e s o u r c e s e e s # o v e r t h e time

# g l o b a l v a r i a b l e s t o s t o r e a l l found p a t h s o f one s r c d e s t p a i r R_T_path [ 0 , 0 ] = 0; R_T_path_index = 0 ; # [ s c h e d u l i n g ] end node_name [ " xcoord " ] node_name [ " ycoord " ] = " X c o o r d i n a t e o f the node " ; = " Y c o o r d i n a t e o f the node " ;

############ DATA p a r t ############### node_name [ " dsAG" ] = " Data p k t s s ent ( generated ) " ; node_name [ " dsout " ] = " The r o ut e i s found , r o u t i n g agent sends the data " ; node_name [ " dsoutB " ] = " The r o ut e i s found , r o u t i n g agent sends data , i n By t es " ; node_name [ " drad " ] = " Data p k t s r e c e i v e d at d es t " ; # n1 ; node_name [ " drf f " ] = " Data p k t s r e c e i v e d f o r f o r w ar d i ng " ; node_name [ " df " ] = " Data p k t s forwarded " ; node_name [ " df" ] = " Data forwarded i n By t es " ; node_name [ " ddt o t a l " ] = " Data p k t s dropped " ; node_name [ " ddt o t a l B " ] = " Data dropped t o t a l i n By t es " ; #ddt o t a l p a c k e t _ s i z e # Drops have many r e a s o n s . . . . node_name [ " ddi f q t o t a l " ] = " Data dropped by i f q t o t a l " ; node_name [ " ddi f q i f q " ] = " Data dropped by i f q because o f o v er f l o w " ; node_name [ " ddi f q arp " ] = " Data dropped by i f q because o f arpproblem " ; node_name [ " ddi f q end " ] = " Data dropped by i f q because o f end o f sim " ; node_name [ " ddr t r t o t a l " ] = " Data dropped by r t r t o t a l " ; node_name [ " ddr t r cbk " ] = " Data dropped by r t r because o f macc a l l back " ; node_name [ " ddr t r t o ut " ] = " Data dropped by r t r because o f time out " ; node_name [ " ddr t r n r t e " ] = " Data dropped by r t r , no r o ut e to host " ; node_name [ " ddr t r end " ] = " Data dropped by r t r because o f end o f sim " ;

218

A.4. Gawk

############ R o u t i n g P r o t o c o l node_name [ " pst o t a l " ] = node_name [ " prt o t a l " ] = node_name [ " pft o t a l " ] = node_name [ " pdt o t a l " ] =

p a r t ############### " T o t a l number o f r o u t i n g " T o t a l number o f r o u t i n g " T o t a l number o f r o u t i n g " T o t a l number o f r o u t i n g

packets packets packets packets

s ent ( check sum ) " ; r e c e i v e d ( check sum ) " ; forwarded " ; dropped ( check sum ) " ;

# Drops have many r e a s o n s . . . . node_name [ " pdi f q t o t a l " ] = " Routing p k t s dropped by i f q node_name [ " pdi f q i f q " ] = " Routing p k t s dropped by i f q node_name [ " pdi f q arp " ] = " Routing p k t s dropped by i f q node_name [ " pdi f q end " ] = " Routing p k t s dropped by i f q node_name [ " pdr t r t o t a l " ] = " Routing p k t s dropped by r t r node_name [ " pdr t r cbk " ] = " Routing p k t s dropped by r t r node_name [ " pdr t r t o ut " ] = " Routing p k t s dropped by r t r node_name [ " pdr t r n r t e " ] = " Routing p k t s dropped by r t r node_name [ " pdr t r end " ] = " Routing p k t s dropped by r t r node_name [ " pdr t r t t l " ] = " Routing p k t s dropped by r t r node_name [ " preqs " ] node_name [ " preqsB " ] node_name [ " preqrt o t " ] node_name [ " preqradunq " ] node_name [ " preqrada l l " ] node_name [ " preqrf f " ] node_name [ " preqf " ] node_name [ " preqfB " ] node_name [ " preqd " ] = = = = = = = = = " RREQ " RREQ " RREQ " RREQ " RREQ " RREQ " RREQ " RREQ " RREQ

total " ; , o v er f l o w " ; , arpproblem " ; , end o f sim " ; total " ; , macc a l l back " ; , time out " ; , no r o ut e to d s t " ; , end o f sim " ; , ttl = 0 " ;

p k t s s ent " ; s ent i n By t es " ; pkts received in t o t al " ; p k t s r e c e i v e d at d es t ( unique ) " ; p k t s r e c e i v e d at d es t ( t o t a l ) " ; p k t s r e c e i v e d f o r f o r w ar d i ng o r as overhead " ; p k t s forwarded " ; forwarded i n By t es " ; p k t s dropped " ;

node_name [ " prepsB " ] = " RREP s ent i n By t es " ; node_name [ " prepsf d " ] = " RREP p k t s s ent from the d e s t i n a t i o n o f the RREQ " ; node_name [ " prepsf i " ] = " RREP p k t s s ent from the i n t e r m e d i a t e node \ t hat knows the path to the d e s t i n a t i o n o f the RREQ " ; node_name [ " preprad " ] = " RREP p k t s r e c e i v e d at d es t " ; node_name [ " preprf f " ] = " RREP p k t s r e c e i v e d f o r f o r w ar d i ng " ; node_name [ " prepf " ] = " RREP p k t s forwarded " ; node_name [ " prepfB " ] = " RREP forwarded i n By t es " ; node_name [ " prepd " ] = " RREP p k t s dropped " ; node_name [ " p er rs " ] = " RERR p k t s s ent " ; node_name [ " p er rsB " ] = " RERR s ent i n By t es " ; node_name [ " p er rr " ] = " RERR p k t s r e c e i v e d " ; # AODV RERR i s a b r o a d c a s t by d e f a u l t node_name [ " p er rf " ] = " RERR p k t s forwarded " ; node_name [ " p er rfB " ] = " RERR forwarded i n By t es " ; node_name [ " p er rd " ] = " RERR p k t s dropped " ; # [ s c h e d u l i n g ] s t a r t node_name [ " ppngs " ] = " PING s ent " ; node_name [ " ppngr " ] = " PING p k t s r e c e i v e d " ; node_name [ " ppngf " ] = " PING p k t s forwarded " ; node_name [ " ppngd " ] = " PING p k t s dropped " ; node_name [ " phels " ] node_name [ " phelr " ] node_name [ " phelf " ] node_name [ " pheld " ] # [ s c h e d u l i n g ] end # . . ARP must be added . # node_name [ " arpdt o t a l " ] node_name [ " preqdarp " ] node_name [ " prepdarp " ] = = = = " HELLO " HELLO " HELLO " HELLO s ent " ; pkts received " ; p k t s forwarded " ; p k t s dropped " ;

= " arpdt o t a l " ; = " preqdarp " ; = " prepdarp " ;

} ########################################################################################## # FUNCTIONS ##########################################################################################

219

A.4. Gawk

f u n c t i o n get_path ( s r c , dest , way , r ecur s i o n_ d ep t h , loop_a , RTST_DEBUG ) { # ge t t h e path from a l l t h e i n f o m a t i o n s from t h e i p a c k e t # f i n d a l l p a t h s from s o u r c e t o d e s t i n a t i o n # s a v e t h e path i n R_T_path RTST_DEBUG = 0 ; #s w i t c h debug on o f f # s e t way way = way "" s r c ; # s e t r e c deep recursion_depth ++; i f ( RTST_DEBUG == 1 ) { p r i n t f ( " working p o i n t i n r e c u r s i o n : %s \ n " , way ) ; p r i n t f ( " \ t r e c deep : %s \ n " , r e c u r s i o n _ d e p t h ) ; p r i n t f ( " \ t s r c : %s \ n " , s r c ) ; p r i n t f ( " \ t d es t : %s \ n " , d es t ) ; p r i n t f ( " \ t number o f next : %s \ n " , r t a b l e [ s r c , dest , " i n f o " , " path number " , " 0 " ] ) ; } i f ( s r c == d es t ) { # at Destination # Save Path i n A r r a y R_T_path_index + + ; R_T_path [ " path " , R_T_path_index ]= way "D" ; R_T_path [ " hops " , R_T_path_index ]= r e c u r s i o n _ d e p t h ; i f ( RTST_DEBUG == 1 ) { p r i n t f ( " way from %s to %s o v er %s with %s hops \ n " , s r c , dest , \ R_T_path [ " path " , R_T_path_index ] , R_T_path [ " hops " , R_T_path_index ] ) ; } return ; } i f ( r e c u r s i o n _ d e p t h < MAX_NODES ) # i f t h e r e c u r s i o n depth i s h i g h e r than t h e number o f nodes i n t h e network , then # we can be s u r e t h a t t h e r e i s a r o u t i n g l o o p { f o r ( l o o p _ a = 1 ; l o o p _ a <= r t a b l e [ s r c , dest , " i n f o " , " path number " , " 0 " ] ; l o o p _ a ++) {# over a l l paths i f ( r t a b l e [ s r c , dest , r t a b l e [ s r c , dest , " i n f o " , " hop next " , l o o p _ a ] , \ r t a b l e [ s r c , dest , " i n f o " , " hop l a s t " , l o o p _ a ] , " s t a t u s " ] == " u " ) # path up ? { # recursion # a s k t h e n e x t hop . . . get_path ( r t a b l e [ s r c , dest , " i n f o " , " hop next " , l o o p _ a ] , dest , way , \ r ecur s i o n_ d ep t h , 0 ) ; } } } else { # r e c u r s i v e deep i s too b i g . . . # . . . n e v e r ending s t o r y ? . . . . p r i n t f ( "## deep max : %s r o u t i n g l o o p ? ? ? ? \ n " , way ) ; } } f u n c t i o n r t a b l e _ s _ t _ p r i n t ( no d e_ s t ar t , node_end , l _ s r c , l _ d s t , l _ p a t h ) { # p r i n t the ro u ti n g ta b l e # HEADER p r i n t f ( " \n " ) ;

220

A.4. Gawk

p r i n t f ( "#RTHST \ t######\n " ) ; p r i n t f ( "#RTHST \ t### RTST###\n " ) ; p r i n t f ( "#RTHST \ t######\n " ) ; p r i n t f ( " \n" ) ; p r i n t f ( "#RTHST_H \ t SRC \ t DEST \ t #PATH \ t PATH \ t UP\ t DOWN\ n " ) ; p r i n t f ( " \n" ) ; f o r ( l _ s r c = n o d e _ s t a r t ; l _ s r c < node_end ; l _ s r c ++) # s r c { f o r ( l _ d s t = n o d e _ s t a r t ; l _ d s t < node_end ; l _ d s t ++)# d e s t { i f ( data_src_dest_table [ l_s r c , l_ds t ]==1) # only source dest { i f ( r t a b l e _ s _ t [ l _ s r c , l _ d s t , " i n f o " , " path number " ] ! = " " ) { f o r ( l _ p a t h = 1 ; l _ p a t h <= r t a b l e _ s _ t [ l _ s r c , l _ d s t , " i n f o " , \ " path number " ] ; l _ p a t h ++) { p r i n t f ( "#RTST \ t " ) ; p r i n t f ( "%s \ t " , l _ s r c ) ; p r i n t f ( "%s \ t " , l _ d s t ) ; p r i n t f ( "%s \ t " , l _ p a t h ) ; p r i n t f ( "%s \ t " , r t a b l e _ s _ t [ l _ s r c , l _ d s t , " i n f o " , l _ p a t h ] ) ; p r i n t f ( " UP%sUP\ t " , r t a b l e _ s _ t [ l _ s r c , l _ d s t , \ r t a b l e _ s _ t [ l _ s r c , l _ d s t , " i n f o " , l _ p a t h ] , " up time " ] ) ; p r i n t f ( "DOWN %s DOWN\ t " , r t a b l e _ s _ t [ l _ s r c , l _ d s t , \ r t a b l e _ s _ t [ l _ s r c , l _ d s t , " i n f o " , l _ p a t h ] , " down time " ] ) ; p r i n t f ( " \n" ) ; } } p r i n t f ( " \n " ) ; } } } p r i n t f ( " \ n\ n " ) ; } f u n c t i o n r t a b l e _ s r c _ p r i n t ( no d e_ s t ar t , node_end , l _ s r c , l _ d s t ) { # p r i n t the r t a b l e _ s r c # HEADER p r i n t f ( " \n" ) ; p r i n t f ( "#RTHSRC \ t### ###\n " ) ; p r i n t f ( "#RTHSRCt### RTST o f Source###\n " ) ; p r i n t f ( "#RTHSRC \ t### ###\n " ) ; p r i n t f ( " \n" ) ; p r i n t f ( "#RTHSRC \ t SRC \ t DEST \ t MIN HOP\ t #PATHS\ t @TIME\ n " ) ; p r i n t f ( " \n" ) ; # DATA f o r ( l _ s r c = n o d e _ s t a r t ; l _ s r c < node_end ; l _ s r c ++) # s r c { f o r ( l _ d s t = n o d e _ s t a r t ; l _ d s t < node_end ; l _ d s t ++)# d e s t { # i s a data c o n n e c t i o n i f ( d a t a _ s r c _ d e s t _ t a b l e [ l _ s r c , l _ d s t ] == 1 ) { p r i n t f ( "#RTSRC \ t " ) ; p r i n t f ( "%s \ t " , l _ s r c ) ; p r i n t f ( "%s \ t " , l _ d s t ) ; p r i n t f ( "%s \ t " , r t a b l e _ s r c [ l _ s r c , l _ d s t , " min hop " ] ) ; p r i n t f ( "%s \ t " , r t a b l e _ s r c [ l _ s r c , l _ d s t , " number o f paths " ] ) ; p r i n t f ( "%s \ t " , r t a b l e _ s r c [ l _ s r c , l _ d s t , " time " ] ) ; p r i n t f ( " \n " ) ; } } } p r i n t f ( " \ n\ n " ) ; }

221

A.4. Gawk

########################################################################################## # PROCESSING OF INPUT F I L E ( s ) ########################################################################################## # # I f I want t o c a l c MAC overhead , I have t o add 52 b y t e s header t o t h e t o t a l o v e r h e a d # /^ r / { i f ( $Time > 1 8 0 ) #remove s t a r t u p phase # [ s c h e d u l i n g ] { TN = $ThisNode ; node [ TN , " xcoord " ] = $Xcoord ; node [ TN , " ycoord " ] = $Ycoord ; i f ( $ P r o t o c o l S t a c k == " R " ) { i f ( $DataOrRouting == " C " ) { i f ( TN ! = s u b s t r ( $ I P_ So ur ceAd d r es s , 1 , i nd ex ( $ I P_ So ur ceAd d r es s , " . " ) 1 ) ) { # check , t h a t i t i s not from t h e AG ( we don t need t o # count i t here , s i n c e i t s counted i n /^ s / where # $ P r o t o c o l S t a c k == "AG " ) node [ TN , " drf f " ] + + ; } # I n AODV , ( u n l i k e DSR ) t h e AGl e v e l r e c e i v e s a data # p a c k e t , i f t h i s p a c k e t i s d e s t i n e d t o t h e c u r r e n t node . # I n DSR , Rl e v e l always r e c e i v e s data p a c k e t s # and then d e c i d e s whether t o f o r w a r d i t o r t o send up t o # AG . # That s why we need not t o c h e c k h e r e i n c a s o f AODV , # t h a t t h e data p a c k e t ( C ) r e c e i v e d by r o u t i n g agent ( R ) # i s not d e s t i n e d t o t h e c u r r e n t node # ( i t cannot be so with AODV ! ) . Data a r r i v a l s t o # d e s t i n a t i o n we count b e l l o w i n $ P r o t o c o l S t a c k == AG . } e l s e i f ( $DataOrRouting == "AODV" ) { node [ TN , " prt o t a l " ] + + ; i f ( $AODV_REQ == " REQ " ) { node [ TN , " preqrt o t " ] + + ; ### numRecReq_AODV[ $AODV_HopCount ] + + ; i f ( TN == $AODV_ReqDest ) { i f ( ! ( ( TN , " preqradunq " , $AODV_BrdcastID , $AODV_ReqSrc ) i n node ) ) { node [ TN , " preqradunq " ] + + ; node [ TN , " preqradunq " , $AODV_BrdcastID , $AODV_ReqSrc ] = 1 ; } node [ TN , " preqrada l l " ] + + ; # # # # # # # # # f r e e memory i n a r r a y , p a c k e t r e a c h e d t h e destination d el ete nodeSentRtPt [ $ s u b s tr ( $IP_SourceAddress , 1 , index ( $ I P _S o u r c eA ddress , " . " ) 1) , $ ] ; I don t do i t , s i n c e , a p a c k e t can a r r i v e to d es t e a r l i e r , that a confirmation i s sent from some o t h e r node

222

A.4. Gawk

} e l s e i f ( ! ( ( TN , " preqrf f " , $AODV_BrdcastID , $AODV_ReqDest , $AODV_ReqSrc ) i n node ) ) { node [ TN , " preqrf f " ] + + ; node [ TN , " preqrf f " , $AODV_BrdcastID , $AODV_ReqDest , $AODV_ReqSrc ] = 1 ; } } e l s e i f ( $AODV_REP == " REP " ) { i f ( TN == s u b s t r ( $ I P _ D e s t A d d r e s s , 1 , i nd ex ( $ I P_ D es t Ad d r es s , " . " ) 1 ) ) { node [ TN , " preprad " ] + + ; } e l s e node [ TN , " preprf f " ] + + ; ## h e r e ( u n l i k e # above ) we don t have o t h e r a l t e r n a t i v e } e l s e i f ( $AODV_ERR == " E " ) { node [ TN , " p er rr " ] + + ; i f ( ! ( ( TN , " p er rr " , $AODV_ErrDest ) i n node ) ) node [ TN , " p er rr " , $AODV_ErrDest ] = 1 ; } # [ s c h e d u l i n g ] s t a r t e l s e i f ( $AODV_PI == " P I " ) { node [ TN , " ppngr " ] + + ; } e l s e i f ( $AODV_HI == " HI " ) { node [ TN , " phelr " ] + + ; } # [ s c h e d u l i n g ] end } } e l s e i f ( $ P r o t o c o l S t a c k == "AG" ) { node [ TN , " drad " ] + + ; r ecv _ t i m e [ $ I P_ U ni q ueI d ] = $Time ; } } } /^ s / { i f ( $Time > 1 8 0 ) #remove s t a r t u p phase # [ s c h e d u l i n g ] { i f ( $ P r o t o c o l S t a c k == "AG" ) { node [ $ThisNode , " dsAG" ] + + ; # if # if p o i n ter to the ( $ I P_ U ni q ueI d p o i n ter to the ( $ I P_ U ni q ueI d lowest_packet_id < l o w e s t _ p a c k e t _ i d ) l o w e s t _ p a c k e t _ i d = $ I P_ U ni q ueI d ; highest_packet_id > h i g h e s t _ p a c k e t _ i d ) h i g h e s t _ p a c k e t _ i d = $ I P_ U ni q ueI d ;

# s a v e send time i n a r r a y send_AG_time [ $ I P_ U ni q ueI d ] = $Time ; } e l s e i f ( $ P r o t o c o l S t a c k == " R " ) { i f ( $DataOrRouting == " C " ) { node [ $ThisNode , " dsout " ] + + ; #h d r S t _ C B R [ i ]+= 5 2 ; # r t S e n t [ i ]+= $ P a c k e t S i z e ;

223

A.4. Gawk

node [ $ThisNode , " dsoutB " ]+= $ P a c k e t S i z e ; send_out_time [ $ I P_ U ni q ueI d ] = $Time ; } e l s e i f ( $DataOrRouting == "AODV" ) { i f ( $AODV_ERR == " E " ) ###??? # S t u p i d i m p l e m e n t a t i on o f AODV RERR doesn t d i r e c t l y # a l l o w t o f i g u r e out , whether i t s a f o r se v e n t . . . { i f ( ( $ThisNode , " p er rr " , $AODV_ErrDest ) i n node ) { node [ $ThisNode , " p er rf " ] + + ; node [ $ThisNode , " p er rfB " ]+= $ P a c k e t S i z e ; } else { node [ $ThisNode , " p er rs " ] + + ; node [ $ThisNode , " p er rsB " ]+= $ P a c k e t S i z e ; } } i f ( $AODV_HopCount == 0 ) # was $AODV_HopCount == 1 but # s h o u l d be ==0 / / [ s c h e d u l i n g ] { node [ $ThisNode , " pst o t a l " ] + + ; # we count a l l # AODV p a c k e t s o r i g i n a t e d ( s e n t ) from t h i s # node . # sendsCntr_AODV + + ; i f ( $AODV_REQ == " REQ " ) { node [ $ThisNode , " preqs " ] + + ; #sendsCntrReq_AODV + + ; node [ $ThisNode , " preqsB " ]+= $ P a c k e t S i z e ; i f ( ! ( ( $ThisNode , " preqrf f " , $AODV_BrdcastID , \ $AODV_ReqDest , $AODV_ReqSrc ) i n node ) ) node [ $ThisNode , " preqrf f " , $AODV_BrdcastID , $AODV_ReqDest , \ $AODV_ReqSrc ] = 1 ; } e l s e i f ( $AODV_REP == " REP " ) { node [ $ThisNode , " prepsf d " ] + + ; # T h i s node i s d e s t i n a t i o n o f RREQ , i t s e n d s t h e # RREP sendsCntrRep_AODV + + ; node [ $ThisNode , " prepsB " ]+= $ P a c k e t S i z e ; } } else { i f ( $AODV_REQ == " REQ " ) { # That s a f o r w a r d e v e n t f o r AODV RREQ node [ $ThisNode , " pft o t a l " ] + + ; #fwCntr_AODV + + ; i f ( $DestMAC == " f " ) # I t s a hack , but . . . ( f o r se v e n t $DestMAC = 0 ) { node [ $ThisNode , " preqf " ] + + ; node [ $ThisNode , " preqfB " ]+= $ P a c k e t S i z e ; } } e l s e i f ( $AODV_REP == " REP " ) { node [ $ThisNode , " prepsf i " ] + + ; # T h i s node i s not t h e d e s t i n a t i o n o f RREQ , but i t # knows t h e r o u t e . # So i t s e n d s t h e RREP with i n i t i a l HopCount = # hops ( t h i s _ n o d e <>d e s t ) + 1 node [ $ThisNode , " prepsB " ]+= $ P a c k e t S i z e ;

224

A.4. Gawk

} } # [ s c h e d u l i n g ] s t a r t i f ( $AODV_PI == " P I " ) { node [ $ThisNode , " ppngs " ] + + ; } e l s e i f ( $AODV_HI == " HI " ) { node [ $ThisNode , " phels " ] + + ; } # [ s c h e d u l i n g ] end } } # I f something i s s e n t ( o r i g i n a t e d ) by t h e r e gi o n , then i t i s " s " event , # o t h e r w i s e i t i s " f " e v e n t } # [ s c h e d u l i n g ] s t a r t # f i n d a l l t h e s r c d s t p a i r s f o r s t a t i s t i c a l r e a s o n s s r c i p = s u b s t r ( $ I P_ So ur ceAd d r es s , 1 , i nd ex ( $ I P_ So ur ceAd d r es s , " . " ) 1 ) ; d s t i p = s u b s t r ( $ I P_ D es t Ad d r es s , 1 , i nd ex ( $ I P_ D es t Ad d r es s , " . " ) 1 ) ; # we want t o know which node i s a s o u r c e i f ( $DataOrRouting == " C " ) { i f ( s r c [ s r c i p ] == 1) { src [ srcip ] = 1 ; } }

# b u i l d source d e s t i n a t i o n ta b l e to r e c o n s t r u c t dataflows # a c t i v a t e DEBUG output data_table_DEBUG = 0 ; i f ( $ P r o t o c o l S t a c k == "AG " ) { i f ( $DataOrRouting == " C " ) { i f ( d a t a _ s r c _ d e s t _ t a b l e [ $ThisNode , s u b s t r ( $ I P_ D es t Ad d r es s , 1 , i nd ex ( $ I P_ D es t Ad d r es s , " . " ) 1 ) ] == " " ) {# f i r s t data p a c k e t d a t a _ s r c _ d e s t _ t a b l e [ $ThisNode , \ s u b s t r ( $ I P_ D es t Ad d r es s , 1 , i nd ex ( $ I P_ D es t Ad d r es s , " . " ) 1 ) ] = 1 ; i f ( data_table_DEBUG == 1 ) { p r i n t f ( " \ n data t a b l e SOURCE %s \ t DESTINATION %s TIME %s \ n " , \ $ThisNode , s u b s t r ( $ I P_ D es t Ad d r es s , 1 , i nd ex ( $ I P_ D es t Ad d r es s , " . " ) 1 ) , $Time ) ; } } e l s e i f ( d a t a _ s r c _ d e s t _ t a b l e [ $ThisNode , \ s u b s t r ( $ I P_ D es t Ad d r es s , 1 , i nd ex ( $ I P_ D es t Ad d r es s , " . " ) 1 ) ] = = " 1 " ) {# a l r e a d y i n t a b l e i f ( data_table_DEBUG == 1 ) { p r i n t f ( " a l r e a d y up \ n " ) ; } } else

225

A.4. Gawk

{ } } } # [ s c h e d u l i n g ] end } /^ f / { i f ( $Time > 1 8 0 ) #remove s t a r t u p phase # [ s c h e d u l i n g ] { i f ( $DataOrRouting == " C " ) { node [ $ThisNode , " df " ] + + ; node [ $ThisNode , " dfB " ]+= $ P a c k e t S i z e ; } e l s e i f ( $DataOrRouting == "AODV" ) { node [ $ThisNode , " pft o t a l " ] + + ; i f ( $AODV_REP == " REP " ) { node [ $ThisNode , " prepf " ] + + ; node [ $ThisNode , " prepfB " ]+= $ P a c k e t S i z e ; } ### T H I S doesn t work with AODV , t h e fe v e n t f o r RERR doesn t ### e x i s t . I t s done l i k e se v e n t ; ### e l s e i f ( $AODV_REP == " E " ) node [ $ThisNode , " p e r r f " ] + + ; #fwCntrErr_AODV ++ # [ s c h e d u l i n g ] s t a r t e l s e i f ( $AODV_PI == " P I " ) { node [ $ThisNode , " ppngf " ] + + ; } e l s e i f ( $AODV_HI == " HI " ) { node [ $ThisNode , " phelf " ] + + ; } # [ s c h e d u l i n g ] end } } } /^d / { i f ( $Time > 1 8 0 ) { d r o p C nt r + + ;

#remove s t a r t u p phase # [ s c h e d u l i n g ]

## T h i s t r e a t s APRd r o p s i n I F Q ( s p e c i a l c a s e ) i f ( $ P r o t o c o l S t a c k == " IFQ " ) { i f ( $ AR P_ i f Ar p == " A " ) { node [ $ThisNode , " arpdt o t a l " ] + + ; i f ( $ARP_PacketType == " REQ " ) { node [ $ThisNode , " preqdarp " ] + + ; } e l s e i f ( $ARP_PacketType == " REP " ) { node [ $ThisNode , " prepdarp " ] + + ; } } }

226

A.4. Gawk

i f ( $DataOrRouting == "AODV" ) { #r t D r [ i ]+= $ P a c k e t S i z e ; i f ( $AODV_REQ == " REQ " ) node [ $ThisNode , " preqd " ] + + ; e l s e i f ( $AODV_REP == " REP " ) node [ $ThisNode , " prepd " ] + + ; e l s e i f ( $AODV_REP == " E " ) node [ $ThisNode , " p er rd " ] + + ; # [ s c h e d u l i n g ] s t a r t e l s e i f ( $AODV_PI == " P I " ) node [ $ThisNode , " ppngd " ] + + ; e l s e i f ( $AODV_HI == " HI " ) node [ $ThisNode , " pheld " ] + + ; # [ s c h e d u l i n g ] end node [ $ThisNode , " pdt o t a l " ] + + ; dropCntr_AODV+ + ; i f ( $ P r o t o c o l S t a c k == " IFQ " ) { node [ $ThisNode , " pdi f q t o t a l " ] + + ; i f ( $ReasonWhyDropped == " | " ) node [ $ThisNode , " pdi f q i f q " ] + + ; e l s e i f ( $ReasonWhyDropped == " ARP " ) node [ $ThisNode , " pdi f q arp " ] + + ; e l s e i f ( $ReasonWhyDropped == " END " ) node [ $ThisNode , " pdi f q end " ] + + ; } e l s e i f ( $ P r o t o c o l S t a c k == " R " ) { node [ $ThisNode , " pdr t r t o t a l " ] + + ; i f ( $ReasonWhyDropped == " CBK " ) node [ $ThisNode , " pdr t r cbk " ] + + ; e l s e i f ( $ReasonWhyDropped == " TOUT " ) node [ $ThisNode , " pdr t r t o ut " ]++ e l s e i f ( $ReasonWhyDropped == " NRTE " ) node [ $ThisNode , " pdr t r n r t e " ] + + ; e l s e i f ( $ReasonWhyDropped == " END " ) node [ $ThisNode , " pdr t r end " ] + + ; e l s e i f ( $ReasonWhyDropped == " TTL " ) node [ $ThisNode , " pdr t r t t l " ] + + ; } } e l s e i f ( $DataOrRouting == " C " ) { #r e c v _ t i m e [ $ I P _ U n i q u e I d ] = 1;# I n v a l i d a t e t h e dropped data pkt s d e l a y # <we p o s s i b l y don t need i t node [ $ThisNode , " ddt o t a l " ] + + ; dropCntr_CBR + + ; i f ( $ P r o t o c o l S t a c k == " IFQ " ) { node [ $ThisNode , " ddi f q t o t a l " ] + + ; i f ( $ReasonWhyDropped == " | " ) node [ $ThisNode , " ddi f q i f q " ] + + ; e l s e i f ( $ReasonWhyDropped == " ARP " ) node [ $ThisNode , " ddi f q arp " ] + + ; e l s e i f ( $ReasonWhyDropped == " END " ) node [ $ThisNode , " ddi f q end " ] + + ; } e l s e i f ( $ P r o t o c o l S t a c k == " R " ) { node [ $ThisNode , " ddr t r t o t a l " ] + + ; i f ( $ReasonWhyDropped == " CBK " ) node [ $ThisNode , " ddr t r cbk " ] + + ; e l s e i f ( $ReasonWhyDropped == " TOUT " ) node [ $ThisNode , " ddr t r t o ut " ] + + ; e l s e i f ( $ReasonWhyDropped == " NRTE " ) node [ $ThisNode , " ddr t r n r t e " ] + + ; e l s e i f ( $ReasonWhyDropped == " END " ) node [ $ThisNode , " ddr t r end " ] + + ; } }

227

A.4. Gawk

} } # [ s c h e d u l i n g ] s t a r t /^ i / { ########### R o u t i n g T a b l e based on INFO PATH PACKETS ############### # IDEA : # # 1 . Copy i n f o r m a t i o n out o f t h e i n f o p a c k e t # 2 . Update g l o b a l r o u t i n g t a b l e ( RT ) # 3 . I f i n f o p a c k e t i s from a data c o n n e c t i o n # s e a r c h a l l path from s r c t o d s t # s a v e new/ up /down p a t h s i n r t _ s _ t # 4 . I f i n f o p a c k e t i s from a data c o n n e c t i o n # s a v e number o f p a t h s from s r c t o d s t # in rt_src # ( 5 . ) End o f s i m u l a t i o n # print rt_s_t # print rt_src # A c t i v a t e Debug output f o r r o u t i n g t a b l e R_T_DEBUG = 0 ; ## F e t c h Data from INFO PACKETS R_T_time = $path_time ; R _ T _ act i o n = $path_action ; R_T_src = $path_src ; R_T_dst = $ p at h_ d s t ; R_T_hop_next = $path_hop_next ; R _ T _ ho p _ l as t = $ p at h_ ho p _ l as t ; R_T_tot_num_path R_T_hop_count R_T_rtt = $path_number_total ; = $path_hop_count ; = $path_rtt ;

# show r e c e i v e d i n f o p a c k e t i f ( R_T_DEBUG == 1 ) { p r i n t f ( " \ n r e c e i v e d p acket at : %s \ n " , p r i n t f ( " a c t i o n : %s \ n " , p r i n t f ( " s r c : %s d es t :% s \ n " , p r i n t f ( " next : %s l a s t %s \ n " , p r i n t f ( " path_number : %s o f %s \ n " , p r i n t f ( " number o f hops to d es t : %s \ n " , }

R_T_time ) ; R _ T _ act i o n ) ; R _ T _ s r c , R_T_dst ) ; R_T_hop_next , R _ T _ ho p _ l as t ) ; R_T_path_number , R_T_tot_num_path ) ; R_T_hop_count ) ;

############################## ## Update R o u t i n g T a b l e ( R_T ) ############################## # # # # rtable rtable rtable rtable [ R_T_src [ R_T_src [ R_T_src [ R_T_src , , , , R_T_dst R_T_dst R_T_dst R_T_dst , , , , " i n f o " , " path number " , " 0 " ] = number o f p a t h s ; " i n f o " , " hop n e x t " , #path_number ] = R_T_hop_next ; " i n f o " , " hop l a s t " , #path_number ] = R _ T _ h o p _ l a s t ; R_T_hop_next , R _ T _ h o p _ l a s t , " s t a t u s " ] = ( u / d ) ;

i f ( R _ T _ act i o n == " 1 " ) # add path { # does path a l r e a d y e x i s t ? i f ( r t a b l e [ R _ T _ s r c , R_T_dst , R_T_hop_next , R _ T _ ho p _ l as t , " s t a t u s " ] == " " ) # path new { # add path r t a b l e [ R _ T _ s r c , R_T_dst , " i n f o " , " path number " , " 0 " ] + + ; r t a b l e [ R _ T _ s r c , R_T_dst , " i n f o " , " hop next " , r t a b l e [ R _ T _ s r c , R_T_dst , \

228

A.4. Gawk

" i n f o " , " path number " , " 0 " ] ] = R_T_hop_next ; r t a b l e [ R _ T _ s r c , R_T_dst , " i n f o " , " hop l a s t " , r t a b l e [ R _ T _ s r c , R_T_dst , \ " i n f o " , " path number " , " 0 " ] ] = R _ T _ ho p _ l as t ; # add new e n t r i e s t o t h e r o u t i n g t a b l e r t a b l e [ R _ T _ s r c , R_T_dst , R_T_hop_next , R _ T _ ho p _ l as t , \ " hop count " ] = R_T_hop_count ; # s e t up f l a g . r t a b l e [ R _ T _ s r c , R_T_dst , R_T_hop_next , R _ T _ ho p _ l as t , " s t a t u s " ] = " u " ; i f ( R_T_DEBUG == 1 ) { p r i n t f ( " add new path ( number %s ) \ n " , r t a b l e [ R _ T _ s r c , R_T_dst , \ " i n f o " , " path number " , " 0 " ] ) ; p r i n t f ( " \ t s r c : %s d es t : %s next : %s l a s t %s \ n " , R _ T _ s r c , R_T_dst , \ R_T_hop_next , R _ T _ ho p _ l as t ) ; p r i n t f ( " \ t hop count : %s \ n " , r t a b l e [ R _ T _ s r c , R_T_dst , R_T_hop_next , \ R _ T _ ho p _ l as t , " hop count " ] ) ; } } e l s e i f ( r t a b l e [ R _ T _ s r c , R_T_dst , R_T_hop_next , R _ T _ ho p _ l as t , " s t a t u s " ] == " d " ) # path was down { # s e t up f l a g r t a b l e [ R _ T _ s r c , R_T_dst , R_T_hop_next , R _ T _ ho p _ l as t , " s t a t u s " ] = " u " ; i f ( R_T_DEBUG == 1 ) { p r i n t f ( " path was down and i s s e t a c t i v e ( number %s ) \ n " , r t a b l e [ R _ T _ s r c , R_T_dst , " i n f o " , " path number " , " 0 " ] ) ; p r i n t f ( " \ t s r c : %s d es t : %s next : %s l a s t %s \ n " , R _ T _ s r c , R_T_dst , \ R_T_hop_next , R _ T _ ho p _ l as t ) ; p r i n t f ( " \ t hop count : %s \ n " , r t a b l e [ R _ T _ s r c , R_T_dst , R_T_hop_next , \ R _ T _ ho p _ l as t , " hop count " ] ) ; } } else { #e r r o r . . . #was a l r e a d y up ? i f ( R_T_DEBUG == 1 ) { p r i n t f ( " path was a l r e a d y up . . . e r r o r ? . . . \ n " ) ; p r i n t f ( " time : %s , s t a t u s %s \ n " , R_T_time , r t a b l e [ R _ T _ s r c , R_T_dst , \ R_T_hop_next , R _ T _ ho p _ l as t , " s t a t u s " ] ) ; p r i n t f ( " s r c : %s d es t :% s \ n " , R _ T _ s r c , R_T_dst ) ; p r i n t f ( " next : %s l a s t %s \ n " , R_T_hop_next , R _ T _ ho p _ l as t ) ; } } } e l s e i f ( R _ T _ act i o n == " 1 " ) { # remove path # does path a l r e a d y e x i s t ? i f ( r t a b l e [ R _ T _ s r c , R_T_dst , R_T_hop_next , R _ T _ ho p _ l as t , " s t a t u s " ] == " " ) #path i s new { # e r r o r s e t path down t h a t does not e x i s t s . . . i f ( R_T_DEBUG == 1 ) { p r i n t f ( " s e t path down t hat t hat does not e x i s t . . . e r r o r ? . . \ n " ) ; p r i n t f ( " time : %s , s t a t u s %s \ n " , R_T_time , r t a b l e [ R _ T _ s r c , R_T_dst , \ R_T_hop_next , R _ T _ ho p _ l as t , " s t a t u s " ] ) ; p r i n t f ( " \ t s r c : %s d es t : %s next : %s l a s t %s \ n " , R _ T _ s r c , R_T_dst , \ R_T_hop_next , R _ T _ ho p _ l as t ) ; p r i n t f ( " \ t hop count : %s \ n " , r t a b l e [ R _ T _ s r c , R_T_dst , R_T_hop_next , \ R _ T _ ho p _ l as t , " hop count " ] ) ;

229

A.4. Gawk

} } e l s e i f ( r t a b l e [ R _ T _ s r c , R_T_dst , R_T_hop_next , R _ T _ ho p _ l as t , " s t a t u s " ] == " u " ) { #path was up # s e t down f l a g r t a b l e [ R _ T _ s r c , R_T_dst , R_T_hop_next , R _ T _ ho p _ l as t , " s t a t u s " ] = " d " ; i f ( R_T_DEBUG == 1 ) { p r i n t f ( " s e t path down ( number %s ) \ n " , r t a b l e [ R _ T _ s r c , R_T_dst , \ " i n f o " , " path number " , " 0 " ] ) ; p r i n t f ( " \ t s r c : %s d es t : %s next : %s l a s t %s \ n " , R _ T _ s r c , R_T_dst , R_T_hop_next , R _ T _ ho p _ l as t ) ; p r i n t f ( " \ t hop count : %s \ n " , r t a b l e [ R _ T _ s r c , R_T_dst , R_T_hop_next , \ R _ T _ ho p _ l as t , " hop count " ] ) ; } } else { # error . . . # path was unknown ? # path was a l r e a d y down? i f ( R_T_DEBUG == 1 ) { p r i n t f ( " s e t path down t hat wasn t up . . . e r r o r ? . . \ n " ) ; p r i n t f ( " time : %s , s t a t u s %s \ n " , R_T_time , r t a b l e [ R _ T _ s r c , R_T_dst , \ R_T_hop_next , R _ T _ ho p _ l as t , " s t a t u s " ] ) ; p r i n t f ( " \ t s r c : %s d es t : %s next : %s l a s t %s \ n " , R _ T _ s r c , R_T_dst , \ R_T_hop_next , R _ T _ ho p _ l as t ) ; p r i n t f ( " \ t hop count : %s \ n " , r t a b l e [ R _ T _ s r c , R_T_dst , R_T_hop_next , \ R _ T _ ho p _ l as t , " hop count " ] ) ; } } } else { # error . . . # unknown a c t i o n i f ( R_T_DEBUG == 1 ) { p r i n t f ( " e r r o r : unknown a c t i o n %s \ n " , R _ T _ act i o n ) ; } } # Show r o u t i n g t a b l e i f ( R_T_DEBUG == 1 ) # i f ( d a t a _ s r c _ d e s t _ t a b l e [ R _ T _ s r c , R _ T _ d s t ] = = 1 ) # o n l y data c o n n e c t i o n s { p r i n t f ( " \ nr o ut i ng t a b l e f o r s r c %s d es t %s at time %s \ n " , R _ T _ s r c , \ R_T_dst , R_T_time ) ; p r i n t f ( " \ t number o f paths : %s \ n " , r t a b l e [ R _ T _ s r c , R_T_dst , " i n f o " , \ " path number " , " 0 " ] ) ; # p r i n t a l l paths f o r ( l o o p _ a = 1 ; l o o p _ a <= r t a b l e [ R _ T _ s r c , R_T_dst , " i n f o " , \ " path number " , " 0 " ] ; l o o p _ a ++) { p r i n t f ( " SRC : %s \ t " , R _ T _ s r c ) ; p r i n t f ( " DEST : %s \ t " , R_T_dst ) ; p r i n t f ( " NEXT HOP : %s \ t " , r t a b l e [ R _ T _ s r c , R_T_dst , " i n f o " , " hop next " , l o o p _ a ] ) ; p r i n t f ( " LAST HOP : %s \ t " , r t a b l e [ R _ T _ s r c , R_T_dst , " i n f o " , " hop l a s t " , l o o p _ a ] ) ; p r i n t f ( " UP/DOWN: %s \ t " , r t a b l e [ R _ T _ s r c , R_T_dst , r t a b l e [ R _ T _ s r c , R_T_dst , \ " i n f o " , " hop next " , l o o p _ a ] , r t a b l e [ R _ T _ s r c , R_T_dst , " i n f o " , \ " hop l a s t " , l o o p _ a ] , " s t a t u s " ] ) ; p r i n t f ( "HOP COUNT : %s \ t " , r t a b l e [ R _ T _ s r c , R_T_dst , r t a b l e [ R _ T _ s r c , R_T_dst , \ " i n f o " , " hop next " , l o o p _ a ] , r t a b l e [ R _ T _ s r c , R_T_dst , " i n f o " , " hop l a s t " , \ l o o p _ a ] , " hop count \ n " ] ) ;

230

A.4. Gawk

} } ############################## ## C a l c u l a t e a l l p o s s i b l e p a t h s from SRC DEST f o r t h e NEXT_HOP f o r a l l d a t a p a t h s ## And s a v e t h e p a t h s i n t h e g l o b a l a r r a y R_T_path ## Only one path s h o u l d be found ! ############################## ## Check i f change a f f e c t s a s o u r c e d e s t i n a t i o n p a i r i f ( ( d a t a _ s r c _ d e s t _ t a b l e [ R _ T _ s r c , R_T_dst ] = = 1 ) | | ( R_T_time < 1 8 0 ) ) { # c a l c u l a t e a l l p o s s i b l e path from s o u r c e t o d e s t R_T_path_index = 0 ; # number o f found p a t h s # ( jump t o n e x t hop and s e a r c h ! ! ! ONLY DEBUG ! ! ! ) #ge t _ p a t h ( R_T_hop_next , R_T_dst , " S " R _ T _ s r c , 0 ) ; # r e c u r s i v e f u n c t i o n t o s e a r c h a l l p a t h s and s a v e t h e p a t h s i n R_T_path get_path ( R _ T _ s r c , R_T_dst , " S " , 0 ) ;

# # # # #

T h e o r e t i c a l l y i t s h o u l d be o n l y one way from x t o y o v e r t h i s n e x t hop , as we assume t o have d i s j o i n t p a t h s . I n p r a c t i c e we f i n d more p a t h s but t h e s o u r c e knows o n l y about one . The r e a s o n f o r t h e m u l t i p l e path i s t h a t not d i s j o i n t path a r e not d e l e t e d , t h e w i l l o n l y be removed by a timeout .

i f ( R_T_DEBUG == 1 ) { i f ( R_T_path_index == 0 ) { # no path from s r c t o d e s t was found i f ( R _ T _ act i o n == 1) { # the i n f o packet r e p o r t s t h i s f a c t # T h i s c a s e i s OK } e l s e i f ( R _ T _ act i o n == 1 ) { # t h e i n f o p a c k e t r e p o r t s a new path but t h i s # path does not e x i s t s i n t h e r o u t i n g t a b l e # Two r e a s o n s : # 1 . Path i s b r o k e n d u r i n g message p a s s i n g # 2 . Path n e v e r e x i s t s > e r r o r # p r i n t f ( " path from s o u r c e t o d e s t i n a t i o n not # found \ n " ) ; } } e l s e i f ( R_T_path_index == 1 ) { # one path from s r c t o d e s t was found i f ( R _ T _ act i o n == 1) { # path was removed but t h e r e i s s t i l l a c o n n e c t i o n # # # # # Two r e a s o n s : 1 . Path was b r o k e n and was r e p a i r e d d u r i n g message p a s s i n g 2 . M u l t i p l e p a t h s a r e c r e a t e d o v e r t h i s hop > e r r o r

# p r i n t f ( " path was removed but t h e r e i s s t i l l a # c o n n e c t i o n between s o u r c e and d e s t \ n " ) ;

231

A.4. Gawk

} e l s e i f ( R _ T _ act i o n == 1 ) { # OK one path was found } } else {# one path from s r c t o d e s t was found i f ( R _ T _ act i o n == 1) { # path was removed but t h e r e i s s t i l l a c o n n e c t i o n # # # # # Two r e a s o n s : 1 . Path was b r o k e n and was r e p a i r e d d u r i n g message p a s s i n g 2 . M u l t i p l e p a t h s a r e c r e a t e d o v e r t h i s hop > e r r o r

# p r i n t f ( " path was removed but t h e r e i s s t i l l a # c o n n e c t i o n between s o u r c e and d e s t \ n " ) ; } e l s e i f ( R _ T _ act i o n == 1 ) { # t h e i n f o p a c k e t r e p o r t s a new path # but m u l t i p l e p a t h s o v e r t h i s hop a r e found # # # # # # # Two r e a s o n s : 1 . F l o o d i n g i n t r o d u c e d more p a t h s a t a i n t e r m e d i a t e node ( a backward path o f a r o u t e req u es t c ro s s ed the source d e s t i n a t i o n path ) 2 . Outdated r o u t i n g i n f o s ? ? NO

# ERROR ! ! ! # p r i n t f ( " more than one path from s o u r c e t o # d e s t i n a t i o n was found \ n " ) ; } } } i f ( R_T_DEBUG == 1 ) { # NORMALLY MORE THAN THE ANNOUNCED PATHS ARE FOUND ! ! ! ! printf printf printf printf printf printf printf ( ( ( ( ( ( ( " Found %s paths f o r : TIME %s \ t " , R_T_path_index , R_T_time ) ; " ACTION %s \ t " , R _ T _ act i o n ) ; " SRC : %s \ t " , R _ T _ s r c ) ; " DEST : %s \ t " , R_T_dst ) ; " NEXT HOP : %s \ t " , R_T_hop_next ) ; " LAST HOP : %s \ t " , R _ T _ ho p _ l as t ) ; " \n " ) ;

f o r ( l o o p _ a = 1 ; l o o p _ a <= R_T_path_index ; l o o p _ a ++) { p r i n t f ( " \ t p at h nr %i : %s r e c u r s i o n depth : %s \ n " , loop_a , \ R_T_path [ " path " , l o o p _ a ] , R_T_path [ " hops " , R_T_path_index ] ) ; } } } ############################## ## update r t a b l e _ s _ t ( s e t up / down time o f t h e p a t h s ) f o r SRC DEST o v e r ## t h i s n e x t hop ## ! ! c o v e r a l l p a t h s found and i s not r e s t r i c t e d t o t h e advanced i n f o r m a t i o n s o f ## t h e s o u r c e r o u t i n g t a b l e ! ! ##############################

232

A.4. Gawk

i f ( ( d a t a _ s r c _ d e s t _ t a b l e [ R _ T _ s r c , R_T_dst ] = = 1 ) | | ( R_T_time < 1 8 0 ) ) { delete R_T_active ; R_T_active [0] = " " ; # c h e c k i f path i s new o r down f o r ( l o o p _ a = 1 ; l o o p _ a <= R_T_path_index ; l o o p _ a ++) { i f ( r t a b l e _ s _ t [ R _ T _ s r c , R_T_dst , R_T_path [ " path " , l o o p _ a ] , " s t a t u s " ] == " " ) # c h e c k i f path i s new { # update " i n f o " # number o f p a t h s r t a b l e _ s _ t [ R _ T _ s r c , R_T_dst , " i n f o " , " path number " ] + + ; # s e t path r t a b l e _ s _ t [ R _ T _ s r c , R_T_dst , " i n f o " , r t a b l e _ s _ t [ R _ T _ s r c , R_T_dst , \ " i n f o " , " path number " ] ] = R_T_path [ " path " , l o o p _ a ] ; # l i n k hash r t a b l e _ s _ t [ R _ T _ s r c , R_T_dst , R_T_path [ " path " , l o o p _ a ] , \ " hash " ] = r t a b l e _ s _ t [ R _ T _ s r c , R_T_dst , " i n f o " , " path number " ] ; # s e t uptime r t a b l e _ s _ t [ R _ T _ s r c , R_T_dst , R_T_path [ " path " , l o o p _ a ] , \ " up time " ] = r t a b l e _ s _ t [ R _ T _ s r c , R_T_dst , \ R_T_path [ " path " , l o o p _ a ] , " up time " ] "" R_T_time ; # set stat flag r t a b l e _ s _ t [ R _ T _ s r c , R_T_dst , R_T_path [ " path " , l o o p _ a ] , " s t a t u s " ] = " u " ; # set active R _ T _ a c t i v e [ r t a b l e _ s _ t [ R _ T _ s r c , R_T_dst , R_T_path [ " path " , l o o p _ a ] , " hash " ] ] = 1 ; i f (0) { p r i n t f ( "NEW: add path %s \ n " , R_T_path [ " path " , l o o p _ a ] ) ; p r i n t f ( " \ t \ tPATH TOTAL %s " , r t a b l e _ s _ t [ R _ T _ s r c , R_T_dst , \ " i n f o " , " path number " ] ) ; p r i n t f ( " PATH : %s " , r t a b l e _ s _ t [ R _ T _ s r c , R_T_dst , " i n f o " , \ r t a b l e _ s _ t [ R _ T _ s r c , R_T_dst , " i n f o " , " path number " ] ] ) ; p r i n t f ( " HASH : %s " , r t a b l e _ s _ t [ R _ T _ s r c , R_T_dst , R_T_path [ " path " , \ l o o p _ a ] , " hash " ] ) ; p r i n t f ( " STAT : %s " , r t a b l e _ s _ t [ R _ T _ s r c , R_T_dst , R_T_path [ " path " , \ loop_a ] , " s t at us " ] ) ; p r i n t f ( " \n " ) ; } } e l s e i f ( r t a b l e _ s _ t [ R _ T _ s r c , R_T_dst , R_T_path [ " path " , l o o p _ a ] , " s t a t u s " ] == " d " ) # c h e c k i f path was down { # s e t uptime r t a b l e _ s _ t [ R _ T _ s r c , R_T_dst , R_T_path [ " path " , l o o p _ a ] , \ " up time " ] = r t a b l e _ s _ t [ R _ T _ s r c , R_T_dst , \ R_T_path [ " path " , l o o p _ a ] , " up time " ] "" R_T_time ; # set stat flag r t a b l e _ s _ t [ R _ T _ s r c , R_T_dst , R_T_path [ " path " , l o o p _ a ] , " s t a t u s " ] = " u " ; # set active R _ T _ a c t i v e [ r t a b l e _ s _ t [ R _ T _ s r c , R_T_dst , R_T_path [ " path " , l o o p _ a ] , " hash " ] ] = 1 ; i f (0) {

233

A.4. Gawk

p r i n t f ( " UP : s e t path %s up \ n " , R_T_path [ " path " , l o o p _ a ] ) ; } } e l s e i f ( r t a b l e _ s _ t [ R _ T _ s r c , R_T_dst , R_T_path [ " path " , l o o p _ a ] , \ " s t a t u s " ] == " u " ) # c h e c k path i s a l r e a d y up {#path was a l r e a d y up # set active R _ T _ a c t i v e [ r t a b l e _ s _ t [ R _ T _ s r c , R_T_dst , R_T_path [ " path " , l o o p _ a ] , \ " hash " ] ] = 1 ; } e l s e # unknown s t a t { p r i n t f ( " unknown s t a t : %s \ n " , r t a b l e _ s _ t [ R _ T _ s r c , \ R_T_dst , R_T_path [ " path " , l o o p _ a ] , " s t a t u s " ] ) ; } } #show a c t i v e s t a t u s i f ( R_T_DEBUG == 1 ) { p r i n t f ( " S t a t u s o f a l l paths \ n " ) ; f o r ( l o o p _ a = 1 ; l o o p _ a <= r t a b l e _ s _ t [ R _ T _ s r c , R_T_dst , " i n f o " , \ " path number " ] ; l o o p _ a ++) { p r i n t f ( " \ t i nd ex : %s Path : %s A c t i v e :% s \ n " , loop_a , r t a b l e _ s _ t [ R _ T _ s r c , \ R_T_dst , " i n f o " , l o o p _ a ] , R _ T _ a c t i v e [ l o o p _ a ] ) ; } } # # # # s e t p a s s i v e p a t h s t o down problem : downpath can not be found i n r o u t i n g t a b l e s o l u t i o n : ALL PATH FOUND PATH == DOWN we used t h e a c t i v e f l a g t o mark a l l found p a t h s

...

f o r ( l o o p _ a = 1 ; loop_a <= r t a b l e _ s _ t [ R _ T _ s r c , R_T_dst , " i n f o " , " path number " ] ; l o o p _ a ++) { # ge t n e x t hop out o f t h i s path s t r i n g s p l i t ( r t a b l e _ s _ t [ R _ T _ s r c , R_T_dst , " i n f o " , l o o p _ a ] , l o o p _ a r r a y , "" ) ; i f ( R_T_DEBUG == 1 ) { i f ( R _ T _ a c t i v e [ l o o p _ a ] == " " && l o o p _ a r r a y [ 3 ] == R_T_hop_next ) { p r i n t f ( " path : %s \ n " , r t a b l e _ s _ t [ R _ T _ s r c , R_T_dst , " i n f o " , l o o p _ a ] ) ; p r i n t f ( " s t a t u s : %s \ n " , r t a b l e _ s _ t [ R _ T _ s r c , R_T_dst , r t a b l e _ s _ t [ R _ T _ s r c , \ R_T_dst , " i n f o " , l o o p _ a ] , " s t a t u s " ] ) ; p r i n t f ( " a c t i v e : %s \ n " , R _ T _ a c t i v e [ l o o p _ a ] ) ; } } i f ( R _ T _ a c t i v e [ l o o p _ a ] == " " && l o o p _ a r r a y [ 3 ] == R_T_hop_next ) {# path was not updated and path f l o w s o v e r t h e # R_T_hop_next ( o t h e r w i s e i t was not found b e c a u s e i t was # not s e a r c h e d ; ) ) i f ( r t a b l e _ s _ t [ R _ T _ s r c , R_T_dst , r t a b l e _ s _ t [ R _ T _ s r c , R_T_dst , " i n f o " , \ l o o p _ a ] , " s t a t u s " ] == " u " ) { # c h e c k i f path was up # path was up , s e t i t down # s e t down time r t a b l e _ s _ t [ R _ T _ s r c , R_T_dst , r t a b l e _ s _ t [ R _ T _ s r c , \ R_T_dst , " i n f o " , l o o p _ a ] , " down time " ] = r t a b l e _ s _ t [ R _ T _ s r c , R_T_dst , \ r t a b l e _ s _ t [ R _ T _ s r c , R_T_dst , " i n f o " , l o o p _ a ] , " down time " ] "" R_T_time ; # set stat flag r t a b l e _ s _ t [ R _ T _ s r c , R_T_dst , r t a b l e _ s _ t [ R _ T _ s r c , R_T_dst , " i n f o " , \

234

A.4. Gawk

loop_a ] , " s t at us " ] = " d " ; i f ( R_T_DEBUG == 1 ) { p r i n t f ( " paths %s i s s e t down\ n " , r t a b l e _ s _ t [ R _ T _ s r c , R_T_dst , \ " i n f o " , r t a b l e _ s _ t [ R _ T _ s r c , R_T_dst , " i n f o " , " path number " ] ] ) ; p r i n t f ( " Time : %s \ t " , R_T_time ) ; p r i n t f ( " ACTION : %s \ t " , R _ T _ act i o n ) ; p r i n t f ( " SRC : %s \ t " , R _ T _ s r c ) ; p r i n t f ( " DEST : %s \ t " , R_T_dst ) ; p r i n t f ( " NEXT HOP : %s \ t " , R_T_hop_next ) ; p r i n t f ( " LAST HOP : %s \ t " , R _ T _ ho p _ l as t ) ; p r i n t f ( " \n" ) ; } } e l s e i f ( r t a b l e _ s _ t [ R _ T _ s r c , R_T_dst , r t a b l e _ s _ t [ R _ T _ s r c , R_T_dst , \ " i n f o " , l o o p _ a ] , " s t a t u s " ] == " d " ) { # path was a l r e a d y down } else { # e r r o r unknown s t a t u s p r i n t f ( " unknown s t a t u s \ n " ) ; } } } } ########################## ## r t a b l e based on s r c i n f o r m a t i o n ########################## # p r o c e s s t h e i n f o r m a t i o n t h a t can be s e e n a t t h e s r c # # # # rtable_src rtable_src rtable_src rtable_src [ R_T_src [ R_T_src [ R_T_src [ R_T_src , , , , R_T_dst R_T_dst R_T_dst R_T_dst , , , , " l a s t number o f p a t h s " ] " time " ] " number o f p a t h s " ] " min hop " ]

# c h e c k i f number o f p a t h s changed # y e s > update # s a v e time # s a v e number o f p a t h s # do n o t h i n g #number o f p a t h s i f ( r t a b l e _ s r c [ R _ T _ s r c , R_T_dst , " l a s t number o f paths " ] == " " ) { #new rtable_src rtable_src rtable_src rtable_src } else { i f ( r t a b l e _ s r c [ R _ T _ s r c , R_T_dst , " l a s t number o f paths " ] ! = R_T_tot_num_path ) {#update r t a b l e _ s r c [ R _ T _ s r c , R_T_dst , " l a s t number o f paths " ]= R_T_tot_num_path ; r t a b l e _ s r c [ R _ T _ s r c , R_T_dst , " time " ] = \ r t a b l e _ s r c [ R _ T _ s r c , R_T_dst , " time " ] "" R_T_time ; r t a b l e _ s r c [ R _ T _ s r c , R_T_dst , " number o f paths " ] = \ r t a b l e _ s r c [ R _ T _ s r c , R_T_dst , " number o f paths " ] "" R_T_tot_num_path ; [ R_T_src [ R_T_src [ R_T_src [ R_T_src , , , , R_T_dst R_T_dst R_T_dst R_T_dst , , , , " l a s t number o f paths " ] = R_T_tot_num_path ; " time " ] = " T" R_T_time ; " number o f paths " ] = "N" R_T_tot_num_path ; " min hop " ] = R_T_hop_count ;

235

A.4. Gawk

i f ( R_T_DEBUG == 1 ) { p r i n t f ( " \ ntime : %s \ n " , R_T_time ) ; p r i n t f ( " number o f paths : %s \ n " , R_T_tot_num_path ) ; p r i n t f ( " timel i n e : %s \ n " , r t a b l e _ s r c [ R _ T _ s r c , R_T_dst , " time " ] ) ; p r i n t f ( "num i n e : %s \ n " , r t a b l e _ s r c [ R _ T _ s r c , R_T_dst , " number o f paths " ] ) ; l } } } #s a v e min hopcount i f ( r t a b l e _ s r c [ R _ T _ s r c , R_T_dst , " min hop " ] > R_T_hop_count ) { r t a b l e _ s r c [ R _ T _ s r c , R_T_dst , " min hop " ] = R_T_hop_count ; } } # [ s c h e d u l i n g ] end ######################################################################################## END { # FILENAME i s b u i l t i n v a r i a b l e t h a t r e f l e c t s t h e name o f t h e p r o c e s s e d f i l e ######## # substr . # UPDATE t h i s a r r a y ,

i f you change node [ ] [ ] & node_name [ ]

############ DATA p a r t ############### names[ 2] = " xcoord " ; names [ 1 ] = " ycoord " ; names [ 0 ] = " dsAG " ; names [ 1 ] = " dsout " ; names [ 2 ] = " drad " ; names [ 3 ] = " drf f " ; names [ 4 ] = " df " ; names [ 5 ] = " ddt o t a l " ; names [ 6 ] = " ddi f q t o t a l " ; names [ 7 ] = " ddi f q i f q " ; names [ 8 ] = " ddi f q arp " ; names [ 9 ] = " ddi f q end " ; names [ 1 0 ] = " ddr t r t o t a l " ; names [ 1 1 ] = " ddr t r cbk " ; names [ 1 2 ] = " ddr t r t o ut " ; names [ 1 3 ] = " ddr t r n r t e " ; names [ 1 4 ] = " ddr t r end " ; ############ R o u t i n g P r o t o c o l p a r t ############### names [ 1 5 ] = " pst o t a l " ; names [ 1 6 ] = " prt o t a l " ; names [ 1 7 ] = " pft o t a l " ; names [ 1 8 ] = " pdt o t a l " ; # Drops have many r e a s o n s . . . . names [ 1 9 ] = " pdi f q t o t a l " ; names [ 2 0 ] = " pdi f q i f q " ; names [ 2 1 ] = " pdi f q arp " ; names [ 2 2 ] = " pdi f q end " ; names [ 2 3 ] = " pdr t r t o t a l " ; names [ 2 4 ] = " pdr t r cbk " ; names [ 2 5 ] = " pdr t r t o ut " ; names [ 2 6 ] = " pdr t r n r t e " ; names [ 2 7 ] = " pdr t r end " ; names [ 2 8 ] = " pdr t r t t l " ; names [ 2 9 ] names [ 3 0 ] names [ 3 1 ] names [ 3 2 ] = = = = " preqs " ; " preqrt o t " ; " preqradunq " ; " preqrada l l " ;

236

A.4. Gawk

names [ 3 3 ] = " preqrf f " ; names [ 3 4 ] = " preqf " ; names [ 3 5 ] = " preqd " ; names [ 3 6 ] names [ 3 7 ] names [ 3 8 ] names [ 3 9 ] names [ 4 0 ] names [ 4 1 ] = = = = = = " prepsf d " " prepsf i " " preprad " " preprf f " " prepf " ; " prepd " ; ; ; ; ;

names [ 4 2 ] = " p er rs " ; names [ 4 3 ] = " p er rr " ; #names [ 4 1 ] = " p e r r rad " ; #names [ 4 2 ] = " p e r r rf f " ; names [ 4 4 ] = " p er rf " ; names [ 4 5 ] = " p er rd " ; # . . ARP must be added . # names [ 4 6 ] = " arpdt o t a l " ; names [ 4 7 ] = " preqdarp " ; names [ 4 8 ] = " prepdarp " ; names [ 4 9 ] names [ 5 0 ] names [ 5 1 ] names [ 5 2 ] names [ 5 3 ] names [ 5 4 ] names [ 5 5 ] names [ 5 6 ] = = = = = = = = " dsoutB " ; " dfB " ; " preqsB " ; " preqfB " ; " prepsB " ; " prepfB " ; " p er rsB " ; " p er rfB " ;

# [ s c h e d u l i n g ] s t a r t names [ 5 7 ] = " ppngs " ; names [ 5 8 ] = " ppngr " ; names [ 5 9 ] = " ppngf " ; names [ 6 0 ] = " ppngd " ; names [ 6 1 ] = " phels " ; names [ 6 2 ] = " phelr " ; names [ 6 3 ] = " phelf " ; names [ 6 4 ] = " pheld " ; # [ s c h e d u l i n g ] end START_INDEX = 2; MAX_TITLES = 6 5 ; p r i n t f ( " Node \ t " ) ; f o r ( names_id = START_INDEX ; names_id < MAX_TITLES ; names_id ++) p r i n t f ( "%s \ t " , names [ names_id ] ) ; p r i n t f ( " \n" ) ; f o r ( node_id = 0 ; node_id < MAX_NODES ; node_id ++) { p r i n t f ( "%d \ t " , node_id ) ; f o r ( names_id = START_INDEX ; names_id < MAX_TITLES ; names_id ++) { tmp = names [ names_id ] ; t o t a l [ names_id ]+= node [ node_id , tmp ] ; p r i n t f ( "%d \ t " , node [ node_id , tmp ] ) ; } p r i n t f ( " \n " ) ; } p r i n t " TOTAL : " ; p r i n t f ( " Node \ n " ) ; f o r ( names_id = START_INDEX ; names_id < MAX_TITLES ; names_id ++)

237

A.4. Gawk

{ p r i n t f ( "%s \ t " , names [ names_id ] ) ; i f ( names_id <65 | | t o t a l [ 6 9 ] == 0) { p r i n t f ( "%s \ n " , t o t a l [ names_id ] ) ; } else { p r i n t f ( "%s \ n " , t o t a l [ names_id ] / t o t a l [ 6 9 ] ) ; } } p r i n t f ( " \n " ) ; # A v e r a ge p k t d e l a y : p r i n t " AVERAGE DATA PACKET DELAY " ; find_r o ut e_cnt r = 0; t r avel_t ime_cnt r = 0; t o t a l _ d e l a y _ c n t r = 0; f o r ( p a c k e t _ i d i n send_AG_time ) { f i n d _ r o u t e = send_out_time [ p a c k e t _ i d ] send_AG_time [ p a c k e t _ i d ] ; t r a v e l _ t i m e = r ecv _ t i m e [ p a c k e t _ i d ] send_out_time [ p a c k e t _ i d ] ; # We have h e r e < , but not < = , s i n c e we wanna count o n l y r e a l d e l a y s # f o r unknown paths , not when t h e path i s known . i f ( send_AG_time [ p a c k e t _ i d ] < send_out_time [ p a c k e t _ i d ] ) { a v r g _ f i n d _ r o u t e += f i n d _ r o u t e ; f i nd _ r o ut e_ cnt r ++; } i f ( send_out_time [ p a c k e t _ i d ] < r ecv _ t i m e [ p a c k e t _ i d ] ) { a v r g _ t r a v e l _ t i m e+= t r a v e l _ t i m e ; t r avel _ t i m e_ cnt r ++; } i f ( send_AG_time [ p a c k e t _ i d ] < r ecv _ t i m e [ p a c k e t _ i d ] ) { a v r g _ t o t a l _ d e l a y += r ecv _ t i m e [ p a c k e t _ i d ] send_AG_time [ p a c k e t _ i d ] ; t o t a l _ d e l a y _ c n t r ++; } } p r i n t f ( "%s \ t%s \ n " p r i n t f ( "%s \ t%s \ n " p r i n t f ( "%s \ t%s \ n " p r i n t f ( "%s \ t%s \ n " , , , , " AVRG time to f i n d a r o ut e " , a v r g _ f i n d _ r o u t e / f i n d _ r o u t e _ c n t r ) ; " AVRG time a data p acket t r a v e l s " , a v r g _ t r a v e l _ t i m e / t r a v e l _ t i m e _ c n t r ) ; " AVRG TOTAL d e l a y o f a data p acket " , a v r g _ t o t a l _ d e l a y / t o t a l _ d e l a y _ c n t r ) ; " RATIO " , t o t a l [ 2 ] / t o t a l [ 0 ] ) ;

p r i n t f ( " \ n%s \ n " , " CHECK I F TRACE WAS COMPLETE " ) ; p r i n t f ( "%s \ t%s \ t%s \ t%s \ n " , " f i r s t data with i d " , l o w e s t _ p a c k e t _ i d , " p acket was s ent at " , \ send_AG_time [ l o w e s t _ p a c k e t _ i d ] ) ; p r i n t f ( "%s \ t%s \ t%s \ t%s \ n " , " l a s t data with i d " , h i g h e s t _ p a c k e t _ i d , " p acket was s ent at " , \ send_AG_time [ h i g h e s t _ p a c k e t _ i d ] ) ; p r i n t f ( " l a s t timestamp \ t%s \ n " , $Time ) ; # [ s c h e d u l i n g ] rtable_s_t_print (0 rtable_src_print (0 # [ s c h e d u l i n g ] } start ,81); ,81); end

Listing A.14: val_to_sim.awk

238

You might also like