6.4.1.1.1.1.7Simulator Output
All output files for test case tcname are placed in the ./out/tcname subdirectory. By placing the output results for each test case in their own directory, it is easier to keep them organized. By placing the outputs in a separate directory from the input parameter settings, the output results can be easily cleaned up, and it is easier to manage the parameter files.
Output from the simulator is in the form of PCAP files and “.out” files. The PCAP files record the output packets along with their timestamps. Comparisons of input PCAP and output PCAP files can be performed to determine the effect of the impairment on, for example, video quality.
The “.out” output files contain delay and packet loss information (in ASCII CSV format) about the simulation result. This information is also implicitly contained in the PCAP file, but because it is not possible to directly indicate packet delay or loss in a PCAP file, the “.out” files are helpful for post analysis. For example, because the “.out” files are in CSV format, they can be read into a spreadsheet programs for analysis.
As described in the section above on the Parameter File, it is not necessary to save output for all of the streams being tested. This can be helpful in conserving disk space, as the output files can be quite large.
6.4.1.1.1.1.8Plotting Results
Scripts are also provided to create plots of packet delay/loss versus time from the “.out” files, as well as plots of packet delay variation (PDV). The script “runone.ss” automatically runs these scripts after running the simulator.
These scripts are written in the “perl” language and depend upon the “gnuplot” utility. Therefore it is necessary to have both perl and gnuplot installed on the machine which will run the post-analysis.
On Windows machines, this needs to be the cygwin version of gnuplot because the perl script pipes the gnuplot commands into gnuplot using a pipe. The version of gnuplot that is used is 4.2.
To make a PNG plot of delay and packet loss from a “.out” file use the “out2png.pl” script. To run this script type the following command:
./src/out2png2.pl out/Dw1/HDTV1_Down.out
To make a PNG plot of the PDV is a two step process. First calculate the histogram statistics using the “out2histo.pl” script, which creates a CSV file. This CSV file can then be plotted with the “histo2png.pl” script:
./src/out2histo.pl out/Dw1/HDTV1_Down.out > out/Dw1/HDTV1_Down-PDV.csv
./histo2png.pl tc/sev1/HDTV1_Down-PDV.csv
6.4.1.1.1.1.9Simulator Internal Conventions
6.4.1.1.1.1.9.1Time
Time in the simulator is represented in units of seconds, and with the type SimTime which is defined as double.
6.4.1.1.1.1.9.2Bits and Bytes
Packets lengths are measured in units of Bytes, and variable names that contain byte quantities include the word “Bytes” in order to make it clear what the units are.
In other places, bits are used (for example in burst sizes for the shaper).
6.4.1.1.1.1.9.3Bit rates
Bit rates in the simulator are represented in units of bits per second, and with the type Bitrate_t which is defined as double.
6.4.1.1.1.1.9.4Priority
Priority levels in the simulator are represented as integers, with smaller numbers representing higher priority packets.
6.4.1.1.1.1.9.5Addresses
Endpoints in the simulation are assigned unique identifiers so that packets may be assigned a source and destination ID. The identifiers are relatively small integer values that serve the same function that L2 or L3 addresses would serve in a real network. Because the simulation model is much simpler than a real L2 or L3 network, and because efficiency of the simulation is important, these identifiers are used instead of actual L2 or L3 addresses.
6.4.1.1.1.1.10Simulator Objects for Network Elements
6.4.1.1.1.1.10.1Packet
A Packet object contains the data for a packet. The members of a Packet object are described briefly in the table below.
-
Packet
|
Transmit Timestamp
|
Sequence Number
|
Priority
|
Source Node ID
|
Destination Node ID
|
Original Packet Length in bytes
|
Next pointer (for PacketQueue)
|
Payload Bytes
|
For efficiency in the simulation, movement of packets is done by passing a pointer to a packet from one object to another. Usually a packet is constructed by a PacketGenerator from a PCAP file, and it is usually deleted when it is received by a PacketMonitor. However, packets can also be lost as a result of Physical link errors (BER) or as a result of Queue congestion.
The Packet Object is derived from the MemRecycler base class.
6.4.1.1.1.1.10.2Port Base Class
Simulator objects such as a Switches or Wires have connection points called Ports. Port objects hold the information necessary to maintain a bidirectional connection between two ports. The transmit side of one port is connected to the receive side of another port at a specified bit rate. Usually the connection is symmetric, but in certain cases, connections can be asymmetric. One example of asymmetry occurs in a typical access link, where the downstream connection operates at a higher bit rate than the upstream connection. Another example of asymmetry occurs in the simulation for packet generation or monitoring, because a packet generator does not receive packets.
Ports never exist as stand-alone entities. The Port base class is always used by derived port types for other objects, , such as WirePorts and SwitchPorts. When a port on derived object is created (such as on a Wire) that derived object defines the Receive action to take when a packet is received. However, the transmit action for a port is not known until two ports are connected together. Indeed, the notion of connecting two ports together is simply a matter of setting the TxAction pointer on one port to point to the Receive action on another port.
The receive action associated with a port is actually a Functor object. Functors are described in more detail later in this document. The purpose of a functor in the Port object is to maintain two pointers: the first is a pointer to the function in the derived port type that will handle the received packet and the second is a pointer to the port itself, so that (for example) the function responsible for receiving packets can keep per-port queue information.
-
Port
|
TxAction pointer
|
RxAction
|
TxBitrate
|
RxBitrate
|
6.4.1.1.1.1.10.3Wire
A Wire object represents a bidirectional physical connection between two network elements, such as switches, routers and firewalls. For each direction, a wire has two properties, delay and bit error rate.
Wire Port[1]
Wire Port[0]
Wire
Rx
Tx
Tx
Rx
BER[0] Delay[0]
BER[1] Delay[1]
The delay of a packet is given in seconds and is independent of bit rate. This makes sense, because for example, the bit rate of an optical fiber or of a twisted pair copper cable is not specified. Instead its physical properties such as propagation speed, bandwidth and loss. The bit rate of a connection is controlled by the endpoints to which it is connected.
-
Wire
|
WirePort[0]
OtherPort Pointer
|
Delay
|
BER
|
TxAction pointer (inherited)
|
RxAction (inherited)
|
|
WirePort[1]
OtherPort Pointer
|
Delay
|
BER
|
TxAction pointer (inherited)
|
RxAction (inherited)
|
|
The wire class also contains two static methods called receive and transmit. The RxAction functor is initialized with 1) a pointer to the receive method, and 2) a pointer to the associated WirePort. When a packet is received on a port, the receive method is called, and it is passed a pointer to the WirePort object as well as a pointer to the Packet. The receive function looks up the appropriate delay value and (assuming it is not lost due to BER) schedules it to be transmitted by telling the dispatcher enqueue an action for this packet at the appropriate time in the future. Packet loss due to BER is simulated as a function of packet size according to the following formula
Pdrop = 1 – (1 - BER)PktLenBits
It is important to note that unlike with a Queue, packets that are dropped due to BER cannot change the transmit time of subsequent packets over that wire. This makes sense because packet loss due to BER cannot be determined until the packet is received and checked (e.g. with frame checksum).
The Wire object has two static methods:
-
receive – receives packets and schedules forwarding
-
transmit – transmits them to the next port
6.4.1.1.1.1.10.4Switch
A Switch object can represent any network element having two or more ports. The purpose of the Switch object is to model common characteristics of network elements, such as store and forward delay, queuing delay, and strict priority QoS.
If a Switch object has just two ports, it can model a network element such as a firewall or modem. If a switch object has more than two ports, it can model a L2 switch or L3 router. A high level view of a switch object is shown below:
Switch Port[0]
Switch Port[2]
Switch Port[3]
Switch Port[1]
Switch (example with 4 ports)
Rx
Tx
Tx
Rx
Forwarding Table
|
DID
|
Eport
|
100
|
0
|
101
|
0
|
10
|
1
|
11
|
1
|
12
|
1
|
13
|
DROP
|
Rx
Tx
Tx
Rx
Each SwitchPort within a switch contains one or more configurable egress queues.
Switch
-
NumPorts
|
Port[]
|
MaxAddr
|
FwdTable
|
Id
|
|
SwitchPort[0]
MySwitch Pointer
|
NumQueues
|
Queue[]
|
PortState (IDLE or ACTIVE)
|
PortNum
|
TxAction pointer (inherited)
|
RxAction (inherited)
|
|
SwitchPort[1]
MySwitch Pointer
|
NumQueues
|
Queue[]
|
PortState (IDLE or ACTIVE)
|
PortNum
|
TxAction pointer (inherited)
|
RxAction (inherited)
|
|
SwitchPort[2]
MySwitch Pointer
|
NumQueues
|
Queue[]
|
PortState (IDLE or ACTIVE)
|
PortNum
|
TxAction pointer (inherited)
|
RxAction (inherited)
|
|
The Switch object has three static methods:
-
receive – implements store/fwd delay and schedules forwarding
-
forward – implements forwarding decision and enqueues in the appropriate egress queue
-
transmit – read packets from highest priority non-empty egress queue and transmit them
Like the Wire object, the switch object initializes the RxAction for each port with a receive function pointer and a pointer to the SwitchPort object. The receive method calculates the store and forward delay associated with each packet by dividing the packet length in bits by the ingress bit rate of the port. After the store and forward delay, the packet is ready to get a forwarding decision. This is implemented by scheduling an event to call the packet forwarding method after an appropriate store and forward delay, and passing pointers to both the switch object and the packet to the forwarding method.
The forwarding method reads the DID (destination ID) of the packet and performs a lookup in the forwarding table. The forwarding table is statically pre-configured by the top-level simulation according to the simulation topology. If the DID is out of range, or if there is no forwarding rule for the specified address, the packet is dropped. Otherwise, the packet is enqueued in the appropriate egress queue (based on the priority of the packet and the availability of Queues). If the egress port is in the IDLE state, its state is changed to ACTIVE and the transmit method is called.
The transmit method examines the output queues and dequeues the highest priority available packet. It then performs the transmit action associated with that port and schedules itself to be called again after the serialization delay of the packet. If there are no packets available to transmit, the egress port marks itself as IDLE and does not schedule itself to be called again.
This model of a switch can be extended in the future to incorporate other features found in more advanced network elements, such as more advanced QoS mechanisms.
6.4.1.1.1.1.10.5PacketQueue
A packet queue object represents a FIFO with limited depth. The elements of a packet queue are as follows:
-
PacketQueue
|
Head Pointer
|
Tail Pointer
|
Fullness (Bytes)
|
MaxDepth (Bytes)
|
The Head and Tail pointers are simply pointers to the first and last packet in the queue. Packets may be enqueued if there is enough space available in the queue to hold the packet. It is assumed that packets can be packed into the queue memory without wasting any memory.
The packets in the queue are maintained as a conventional linked list.
6.4.1.1.1.1.11Simulator Input and Output Objects
6.4.1.1.1.1.11.1PacketGeneratorPCAP
The PacketGeneratorPCAP object reads packets from a PCAP file and drives them into the simulation. It is derived from a Port object. The following table shows the parameters, internal states and inherited members for it.
-
PacketGeneratorPCAP
|
Parameters
|
Internal State
|
Inherited Members
|
Filename
|
File pointer
|
TxAction pointer
|
SID / DID
|
Sequence Number
|
RxAction
|
Start Delay
|
LittleEndian
|
TxBitrate
|
Bandwidth Scale Factor
|
NanoTime
|
RxBitrate
|
PPM Offset
|
First Packet Timestamp
|
|
Randomness
|
Shaper State
|
Priority
|
|
Repeat Count
|
Shaper PIR
|
Shaper PBS
|
-
Filename – the file name of the input PCAP file (may be relative or absolute).
-
DID/SID – the source and destination ID of the packets that this PacketGeneratorPCAP sends. It has no relation to the actual addresses of the packets in the file. See the section on Address conventions for more information.
-
Start Delay – the relative delay, in seconds, before starting generator.
-
Bandwidth Scale Factor – a scale factor that divides the relative timestamps in the PCAP file. A value of 1.0 makes no change to the timing of the packets. A value of 2.0 causes the packets to be transmitted twice as fast by dividing the timestamps in the PCAP file by 2.0.
-
PPM offset – this is similar to the Bandwidth Scale Factor, but is expressed in units of parts per million. A value of 0 ppm makes no change to the rate at which packets are generated. A value of 100ppm reduces the timestamps in the PCAP file by 100 ppm, which causes the file to be transmitted 100 ppm faster than nominal.
-
Randomness – this is a value from 0.0 to 1.0 that adds a percentage of randomness to the inter-packet times. A value of 0.5 represents 50% randomness for inter-packet timing. What this means, is that if the time between two consecutive packets in the PCAP file is 1 millisecond, and the randomness is 0.5, then the actual time between those two consecutive packets could be in the range 500 microsecond to 1.5 millisecond.
-
Priority – this is the assigned priority of the packets
-
Repeat Count – this is the number of times to repeat the PCAP file. A value of 0 or 1 means to play the file once, a value of two or more will play the file that many times, and a value of -1 will repeat the file forever.
-
Shaper PIR and Shaper PBS – these parameters control a shaper that is built into the PacketGeneratorPCAP object. The PIR is the Peak Information Rate and is expressed in bits per second, so the value 10E6 represents 10 million bits per second. The PBS is the Peak Burst Size and is expressed in bits. These options are useful if the PCAP file is has bursts or microbursts.
6.4.1.1.1.1.11.2PacketMonitorPCAP
The PacketMonitorPCAP object receives packets from a Switch and saves them to an output PCAP file, and also saves the delay and loss information for those packets to an ASCII CSV “.out” file.
The following table shows the parameters, internal states and inherited members for it.
-
PacketMonitorPCAP
|
Parameters
|
Internal State
|
Inherited Members
|
CSV File Name
|
CSV File pointer
|
TxAction pointer
|
PCAP File Name
|
PCAP File Pointer
|
RxAction
|
SID / DID
|
Packet Count
|
TxBitrate
|
Description
|
Last Seq Number
|
RxBitrate
|
-
CSV File Name – this is the name of the “.out” CSV file
-
PCAP File Name – this is the name of the PCAP output file
-
SID/DID – this is source and destination ID pair that this monitor should look for. It will ignore all packets that do not match the SID/DID that is configured.
-
Description – this is a description of the output that is placed at the top of the “.out” file
6.4.1.1.1.1.11.3“.out” File Format
The “.out” file format is a standard ASCII CSV format with three columns. The first column is the simulation time in seconds that the packet was transmitted, the second column is usually Delay (usually in milliseconds, other units can be specified in the header) and the third column is usually a Drop flag (1 means drop, 0 means successful delivery). The delay units and column order can be changed by adjusting the column headings and the Delay Unit header field.
The “.out” file has a header with additional information.
An example is shown below:
Source:,"TIA TR30.3: TIA-921B"
Creation Date:,05/05/2010
Description:, out/tc/basename
Content-Encoding :, ASCII
Delay Unit:,ms
Time, Delay, Drop
0.000000000,22.518541212,0
0.019323502,22.518541212,0
0.021047588,22.518541212,0
0.021869050,22.518541212,0
0.023355058,22.518541212,0
0.025128660,22.518541212,0
2.000000000,14.241843818,0
2.217940424,14.022805455,0
2.221329923,14.145793333,0
2.292414978,14.102274545,0
2.559969646,14.023562303,0
3.161421736,21.071927650,0
3.235437406,30.352536693,0
3.236295847,30.536035327,1
3.414751156,18.975278612,0
3.563506112,36.299552277,0
3.678545565,17.087872868,0
3.964892379,14.022805455,0
3.970588431,14.573034303,0
3.972389489,14.573034303,0
3.974369414,15.531071169,0
3.975693763,14.578600829,0
4.010895351,14.573034303,0
4.011520585,15.026588428,0
4.026753201,21.923139616,1
4.910704084,14.106815636,0
6.4.1.1.1.1.12Other Base Classes
6.4.1.1.1.1.12.1MemRecycler
MemRecycler is a template base class that overrides the default new and delete operators. The replacement new and delete operators maintain a stack of available memory buffers that can be very quickly O(1) accessed. If there are no buffers available in the linked list, then another one is obtained from malloc().
This strategy works well in situations where a few types of fixed size objects must be quickly created and destroyed for three reasons
-
It avoids the overhead of using malloc() for every allocation. For many situations, the MemRecycler object will reach a point where enough buffers of each type have been allocated and these buffers keep being reused for the remainder of program execution.
-
There is a separate stack for each template type, meaning that every element in the stack is exactly the right size.
-
The elements in the stack are used in LIFO order, which may help maintain locality of reference for efficient use of virtual memory and/or CPU cache.
6.4.1.1.1.1.13Simulator Objects for Discrete Event Simulation
6.4.1.1.1.1.13.1Action
An Action is simply a pointer to a function taking two void pointers. Example actions include the receive and transmit methods for Wire and Switch objects.
typedef void (*Action)(void *, void *);
6.4.1.1.1.1.13.2Functor
In this simulation, a Functor object is a combination of an Action pointer and an object pointer. The function call operator is overloaded in the Functor class, so that “calling” a Functor object with a void pointer results in invoking the function referred to by the Action pointer, and providing the object pointer as the first argument and the void pointer as the second argument.
class Functor
{
public:
Functor(Action action, void *arg1) : mAction(action), mArg1(arg1) { };
inline void operator()(void *arg2) { (*mAction)(mArg1,arg2); }
private:
Action mAction;
void *mArg1;
}
The purpose of a functor is to encapsulate the function pointer and the first argument pointer for that function. This is a common way to mimic the behavior of a closure in C++.
6.4.1.1.1.1.13.3Event
An Event object holds an action, the arguments for the Action and the time at which to execute the action. The purpose of an event is to encapsulate something that needs to happen at a time in the future.
The event object is derived from the MemRecycler base class for efficiency reasons.
Event objects have a Doit() method that invokes the specified Action with the specified arguments.
6.4.1.1.1.1.13.4Dispatcher/Scheduler
The Dispatcher object maintains a list of events in sorted order, with the soonest event first. Other objects in the simulator, such as Wires and Switches may schedule events by calling the Scheduler routines. There are two scheduler routines:
-
ScheduleAt – Schedules an event to occur at an absolute time in the future. This can be used to schedule events to occur at precise times that are not dependent on the current simulation time.
-
ScheduleIn – Schedules an event to occur at a relative time in the future. This can be used to schedule events to occur at a precise amount of time after the current simulator time.
The event list maintained by the scheduler is held in a Red-Black tree.
The initialization routine for the Dispatcher must be called early in the simulation to ensure that it is ready to receive events. This can be done with the following code
Dispatcher::Initialize();
The dispatcher can be started in one of two ways:
-
RunTill(T) – Invokes the dispatcher to execute events until the time reaches T, or there are no more events to execute
-
RunFor(T) – Invokes the dispatcher to execute events for T seconds, or there are no more events to execute.
When running, the dispatcher removes the event with the smallest time from the event list. If that event is at a time in the future, the Dispatcher sets the simulator’s current time to the time of that event and then it executes the event.
At the end of a simulation, it is good practice to shut down the Dispatcher by calling the ShutDown method
Dispatcher::ShutDown();
The dispatcher object is a singleton class.
6.4.1.1.1.1.13.5Red-Black Tree
As mentioned above, the Dispatcher keeps a list of Events in sorted order. It uses a Red-Black tree to do this. A Red-Black tree is a type of binary tree which is partially balanced. Specifically, the tree is balanced such that the in the worst case, the longest root-to-leaf path is no more than twice as long as the shortest root-to-leaf path. This ensures that insertion, deletion and other operations are always O(log N) in complexity.
Because the worst case performance of operations on the Red-Black tree is guaranteed to be O(log N), and because the additional overhead of the self-balancing is relatively minor, Red-Black trees are well suited for a variety of applications, such as scheduling events.
For more information on Red-Black trees, refer to
http://en.wikipedia.org/wiki/Red-black_tree
6.4.1.1.1.1.14Numbering conventions in the top Level Simulator (CORE2LAN.cpp)
The general numbering convention for source ID and destination ID is to assign IDs from 1 to 50 to nodes in the core of the network, and to assign IDs from 100 to 150 to the Remote LAN network (inside the home). The reason for doing this is that it makes it easy to configure the forwarding tables inside the switches, routers, modems, firewalls etc within the simulation.
There are 15 IDs in the core of the network
IDs in the Network Core
|
Name
|
ID
|
Description
|
SRV1
|
10
|
Server 1 at CoreSw[0].Port(2)
|
SRV2
|
11
|
Server 2 at CoreSw[0].Port(3)
|
SRV3
|
12
|
Server 3 at CoreSw[0].Port(4)
|
SRV4
|
13
|
Server 4 at CoreSw[0].Port(5)
|
SRV5
|
14
|
Server 5 at CoreSw[0].Port(6)
|
SRV6
|
15
|
Server 6 at CoreSw[0].Port(7)
|
SRV7
|
16
|
Server 7 at CoreSw[0].Port(8)
|
SRV8
|
17
|
Server 8 at CoreSw[0].Port(9)
|
SRV9
|
18
|
Server 9 at CoreSw[0].Port(10)
|
SRV10
|
19
|
Server 10 at CoreSw[0].Port(11)
|
SRV11
|
20
|
Server 11 at CoreSw[0].Port(12)
|
SRV12
|
21
|
Server 12 at CoreSw[0].Port(13)
|
SRV13
|
22
|
Server 13 at CoreSw[0].Port(14)
|
SRV14
|
23
|
Server 14 at CoreSw[0].Port(15)
|
SRV15
|
24
|
Server 15 at CoreSw[0].Port(16)
|
There are 15 IDs in the remote (home) network
IDs in the Remote (Home)
|
Name
|
ID
|
Description
|
PC1
|
101
|
Home PC #1
|
PC2
|
102
|
Home PC #2
|
STB1
|
103
|
Set Top Box #1
|
STB2
|
104
|
Set Top Box #2
|
STB3
|
105
|
Set Top Box #3
|
STB4
|
106
|
Set Top Box #4
|
STB5
|
107
|
Set Top Box #5
|
STB6
|
108
|
Set Top Box #6
|
STB7
|
109
|
Set Top Box #7
|
STB8
|
110
|
Set Top Box #8
|
STB9
|
111
|
Set Top Box #9
|
STB10
|
112
|
Set Top Box #10
|
STB11
|
113
|
Set Top Box #11
|
STB12
|
114
|
Set Top Box #12
|
STB13
|
115
|
Set Top Box #13
|
The assignment of PacketGenerator instance names to IDs is as follows:
Packet Generator Instance Name to SID/DID
|
Name
|
SID
|
DID
|
PktGenPCAPFwdI1
|
SRV1 (10)
|
PC1 (101)
|
PktGenPCAPFwdI2
|
SRV1 (10)
|
PC2 (102)
|
PktGenPCAPFwdI3
|
SRV1 (10)
|
STB1 (103)
|
PktGenPCAPFwdI4
|
SRV1 (10)
|
STB2 (104)
|
PktGenPCAPFwdI5
|
SRV1 (10)
|
STB3 (105)
|
PktGenPCAPFwdI6
|
SRV1 (10)
|
STB4 (106)
|
PktGenPCAPFwdI7
|
SRV1 (10)
|
STB5 (107)
|
PktGenPCAPFwdI8
|
SRV1 (10)
|
STB6 (108)
|
PktGenPCAPFwdI9
|
SRV1 (10)
|
STB7 (109)
|
PktGenPCAPFwdI10
|
SRV1 (10)
|
STB8 (110)
|
PktGenPCAPFwdI11
|
SRV1 (10)
|
STB9 (111)
|
PktGenPCAPFwdI12
|
SRV1 (10)
|
STB10 (112)
|
PktGenPCAPFwdI13
|
SRV1 (10)
|
STB11 (113)
|
PktGenPCAPFwdI14
|
SRV1 (10)
|
STB12 (114)
|
PktGenPCAPFwdI15
|
SRV1 (10)
|
STB13 (115)
|
The assignment of PacketMonitor instance names to IDs is as follows:
Packet Monitor Instance Name to SID/DID
|
Name
|
SID
|
DID
|
PktMonPCAPFwdI1
|
SRV1 (10)
|
PC1 (101)
|
PktMonPCAPFwdI2
|
SRV1 (10)
|
PC2 (102)
|
PktMonPCAPFwdI3
|
SRV1 (10)
|
STB1 (103)
|
PktMonPCAPFwdI4
|
SRV1 (10)
|
STB2 (104)
|
PktMonPCAPFwdI5
|
SRV1 (10)
|
STB3 (105)
|
PktMonPCAPFwdI6
|
SRV1 (10)
|
STB4 (106)
|
PktMonPCAPFwdI7
|
SRV1 (10)
|
STB5 (107)
|
PktMonPCAPFwdI8
|
SRV1 (10)
|
STB6 (108)
|
PktMonPCAPFwdI9
|
SRV1 (10)
|
STB7 (109)
|
PktMonPCAPFwdI10
|
SRV1 (10)
|
STB8 (110)
|
6.4.1.1.1.1.15File List
The following is a list of files that make up the simulator from the top level directory “./”. There are four primary subdirectories of sim, namely the pcap input files, the simulator source code, the test case parameter files (tc) and the output results directory.
./pcap
./src
./tc
./out
Within the top level “./” directory, there are also two convenience scripts for running the simulator, as described earlier:
./runall.ss
./runone.ss
The simulator input PCAP files are in the pcap/ subdirectory. Since these files are large, they are typically distributed separately from the model source code, and often the pcap subdirectory is a soft-link to a separate directory. Here is a list of typical input PCAP files.
pcap/HD_cbr.pcap
pcap/HD_vbr.pcap
pcap/SD_cbr.pcap
pcap/SD_vbr.pcap
pcap/P2P_Down.pcap
pcap/P2P_Up.pcap
pcap/OTT1_Down.pcap
pcap/OTT1_Up.pcap
pcap/OTT2_Down.pcap
pcap/OTT2_Up.pcap
pcap/voip_g729_fwd.pcap
pcap/voip_g729_rev.pcap
pcap/ipfax_v34_t38_fwd.pcap
pcap/ipfax_v34_t38_rev.pcap
The C++ and C source code is in the sim/src directory:
./src/Action.h
./src/Bitrate.h
./src/CORE2LAN.cpp
./src/CORE2LAN_Defaults.h
./src/Clock.cpp
./src/Clock.h
./src/Dispatcher.cpp
./src/Dispatcher.h
./src/Event.cpp
./src/Event.h
./src/Functor.h
./src/Makefile
./src/MemRecycler.h
./src/PCAP.h
./src/Packet.cpp
./src/Packet.h
./src/PacketGenerator.cpp
./src/PacketGenerator.h
./src/PacketGeneratorPCAP.cpp
./src/PacketGeneratorPCAP.h
./src/PacketMonitor.cpp
./src/PacketMonitor.h
./src/PacketMonitorPCAP.cpp
./src/PacketMonitorPCAP.h
./src/PacketQueue.cpp
./src/PacketQueue.h
./src/PacketRO.cpp
./src/PacketRO.h
./src/Port.cpp
./src/Port.h
./src/SimParam.cpp
./src/SimParam.h
./src/Switch.cpp
./src/Switch.h
./src/Wire.cpp
./src/Wire.h
./src/bin.debug
./src/bin.debug/CORE2LAN.exe
./src/histo2png.pl
./src/out2histo.pl
./src/out2png2.pl
./src/proc.info.pl
./src/redblack.c
./src/redblack.h
Within the source subdirectory there are several plotting utilities written in Perl
./src/histo2png.pl
./src/out2histo.pl
./src/out2png2.pl
The individual test case parameter files are in the sim/tc directory.:
./tc/Dp1.param
./tc/Dp2.param
./tc/Dp3.param
./tc/Dp4.param
./tc/Dp5.param
./tc/Dp6.param
./tc/Dp7.param
./tc/Du1.param
./tc/Du2.param
./tc/Du3.param
./tc/Du4.param
./tc/Du5.param
./tc/Du6.param
./tc/Du7.param
./tc/Dw1.param
./tc/Dw2.param
./tc/Dw3.param
./tc/Dw4.param
./tc/Dw5.param
./tc/Dw6.param
./tc/Dw7.param
./tc/Dw8.param
./tc/Gp1.param
./tc/Gp2.param
./tc/Gp3.param
./tc/Gp4.param
./tc/Gp5.param
./tc/Gp6.param
./tc/Gp7.param
./tc/Gu1.param
./tc/Gu2.param
./tc/Gu3.param
./tc/Gu4.param
./tc/Gu5.param
./tc/Gu6.param
./tc/Gu7.param
./tc/Gw1.param
./tc/Gw2.param
./tc/Gw3.param
./tc/Gw4.param
./tc/Gw5.param
./tc/Gw6.param
./tc/Gw7.param
./tc/Gw8.param
./tc/core.param
When a test case is run a log file of results is maintained in the info.log file. This is mainly for regression testing the simulation.
./info.log
The output results for each test case are placed in a subdirectory of the “sim/out” directory. For each PacketMonitorPCAP that Is configured in the parameter file, there is an output PCAP file and an output “.out” file (described below). The scripts for automatically running the simulation and postprocesses create plots of delay/jitter and packet loss versus time and also plot a histogram of delay. The plots are in PNG format.
./out/Dw1
./out/Dw1/Dw1-Fax_v34_t38_Fwd-PDV.png
./out/Dw1/Dw1-Fax_v34_t38_Fwd.png
./out/Dw1/Dw1-Fax_v34_t38_Rev-PDV.png
./out/Dw1/Dw1-Fax_v34_t38_Rev.png
./out/Dw1/Dw1-HDTV1_Down-PDV.png
./out/Dw1/Dw1-HDTV1_Down.png
./out/Dw1/Dw1-VoIP1_Fwd-PDV.png
./out/Dw1/Dw1-VoIP1_Fwd.png
./out/Dw1/Dw1-VoIP1_Rev-PDV.png
./out/Dw1/Dw1-VoIP1_Rev.png
./out/Dw1/Fax_v34_t38_Fwd-PDV.csv
./out/Dw1/Fax_v34_t38_Fwd.out
./out/Dw1/Fax_v34_t38_Fwd.pcap
./out/Dw1/Fax_v34_t38_Rev-PDV.csv
./out/Dw1/Fax_v34_t38_Rev.out
./out/Dw1/Fax_v34_t38_Rev.pcap
./out/Dw1/HDTV1_Down-PDV.csv
./out/Dw1/HDTV1_Down.out
./out/Dw1/HDTV1_Down.pcap
./out/Dw1/VoIP1_Fwd-PDV.csv
./out/Dw1/VoIP1_Fwd.out
./out/Dw1/VoIP1_Fwd.pcap
./out/Dw1/VoIP1_Rev-PDV.csv
./out/Dw1/VoIP1_Rev.out
./out/Dw1/VoIP1_Rev.pcap
./out/Dw1/info.log
./tc/common.tcl
There are two convenience scripts to help run the simulation and plot results
runcl.ss
runcl_plotone.ss
6.4.1.1.1.1.16Common TCL file
There is one TCL support file that helps with setting up simulation parameters
./tc/common.tcl
The common TCL support file “common.tcl” helps simplify the process of setting variables for the PCAP generators and monitors.
The first thing that the common.tcl file does is create the output directory and set the variable $outdir
# - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
# Create the output directory
# - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
set outroot "out"
set outdir [file join $outroot [file rootname [file tail $paramfile]]]
file mkdir $outdir
The next routine “gset” is a general purpose routine for setting a global variable
# - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
# gset -- set a variable at global scope
# - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
proc gset {name value} {
upvar \#0 $name $name
set $name $value
}
The next routine defines parameters for a PCAP generator
# - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
# Define parameters for a PCAP Generator
# - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
proc PCAP_Generator {name file {start ""} {bwscale ""} {ppm ""} \
{rand ""} {prio ""} {rept ""} {PIR ""} {PBS ""}} {
gset ${name}_FileName "pcap/$file.pcap"
if {$start != ""} { gset ${name}_StartDelay $start }
if {$bwscale != ""} { gset ${name}_BW_Scale $bwscale }
if {$ppm != ""} { gset ${name}_PPM_Offset $ppm }
if {$rand != ""} { gset ${name}_Randomness $rand }
if {$prio != ""} { gset ${name}_Priority $prio }
if {$rept != ""} { gset ${name}_RepeatCnt $rept }
if {$PIR != ""} { gset ${name}_ShaperPIR $PIR }
if {$PBS != ""} { gset ${name}_ShaperPBS $PBS }
}
The next routine defines parameters for a PCAP monitor
# - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
# Define parameters for a PCAP Monitor
# - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
proc PCAP_Monitor {name file} {
global outdir
gset ${name}_OutFileName "$outdir/$file.out"
gset ${name}_PCAPFileName "$outdir/$file.pcap"
}
The next routines help to set network parameters for the access link
# - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
# Set Global Vars for Access Link Parameters
# - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
proc _Access_Params {name
{SpeedDown ""}
{SpeedUp ""}
{BER_Fwd ""}
{BER_Rev ""}
{LatencyDown ""}
{LatencyUp ""}} {
if {$SpeedDown != ""} { gset ${name}_SpeedDown $SpeedDown }
if {$SpeedUp != ""} { gset ${name}_SpeedUp $SpeedUp }
if {$BER_Fwd != ""} { gset ${name}_BER_Fwd $BER_Fwd }
if {$BER_Rev != ""} { gset ${name}_BER_Rev $BER_Rev }
if {$LatencyDown != ""} { gset ${name}_LatencyDown $LatencyDown }
if {$LatencyUp != ""} { gset ${name}_LatencyUp $LatencyUp }
if {$ReorderProb != ""} { gset RO_Fwd_Prob $ReorderProb }
if {$ReorderProb != ""} { gset RO_Rev_Prob $ReorderProb }
}
# - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
# Select a set of access link parameters based on name
# - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
proc Set_Access_Params {paramset} {
# Node SpdDn SpdUp BER_Fwd BER_Rev LatcyDn LatcyUp
if {$paramset == "dsl_w1"} { _Access_Params RACC 33e6 3e6 1e-8 1e-8 1e-3 1e-3
} elseif {$paramset == "dsl_w2"} { _Access_Params RACC 33e6 3e6 1e-8 1e-8 1e-3 1e-3
} elseif {$paramset == "dsl_w3"} { _Access_Params RACC 33e6 3e6 1e-8 1e-8 1e-3 1e-3
} elseif {$paramset == "dsl_w4"} { _Access_Params RACC 22e6 2e6 1e-8 1e-8 1e-3 1e-3
} elseif {$paramset == "dsl_w5"} { _Access_Params RACC 16e6 1e6 1e-7 1e-7 1e-3 1e-3
} elseif {$paramset == "dsl_w6"} { _Access_Params RACC 16e6 1e6 1e-7 1e-7 1e-3 1e-3
} elseif {$paramset == "dsl_w7"} { _Access_Params RACC 16e6 1e6 1e-7 1e-7 1e-3 1e-3
} elseif {$paramset == "dsl_w8"} { _Access_Params RACC 10e6 1e6 1e-7 1e-7 1e-3 1e-3
} elseif {$paramset == "pon_w1"} { _Access_Params RACC 50e6 25e6 1e-12 1e-12 1e-3 1e-3
} elseif {$paramset == "pon_w2"} { _Access_Params RACC 50e6 25e6 1e-12 1e-12 1e-3 1e-3
} elseif {$paramset == "pon_w3"} { _Access_Params RACC 35e6 25e6 1e-11 1e-11 1e-3 1e-3
} elseif {$paramset == "pon_w4"} { _Access_Params RACC 35e6 25e6 1e-11 1e-11 1e-3 1e-3
} elseif {$paramset == "pon_w5"} { _Access_Params RACC 25e6 25e6 1e-10 1e-10 1e-3 1e-3
} elseif {$paramset == "pon_w6"} { _Access_Params RACC 25e6 25e6 1e-9 1e-9 1e-3 1e-3
} elseif {$paramset == "pon_w7"} { _Access_Params RACC 25e6 25e6 1e-9 1e-9 1e-3 1e-3
} elseif {$paramset == "pon_w8"} { _Access_Params RACC 15e6 5e6 1e-9 1e-9 1e-3 1e-3
} elseif {$paramset == "pon_p1_u1"} { _Access_Params RACC 35e6 35e6 1e-12 1e-12 1e-3 1e-3
} elseif {$paramset == "pon_p2_u2"} { _Access_Params RACC 35e6 15e6 1e-12 1e-12 1e-3 1e-3
} elseif {$paramset == "pon_p3_u3"} { _Access_Params RACC 25e6 25e6 1e-11 1e-11 1e-3 1e-3
} elseif {$paramset == "pon_p4_u4"} { _Access_Params RACC 15e6 5e6 1e-9 1e-9 1e-3 1e-3
} elseif {$paramset == "pon_p5_u5"} { _Access_Params RACC 5e6 2e6 1e-9 1e-9 1e-3 1e-3
} elseif {$paramset == "pon_p6_u6"} { _Access_Params RACC 15e6 5e6 1e-9 1e-9 1e-3 1e-3
} elseif {$paramset == "pon_p7_u7"} { _Access_Params RACC 5e6 2e6 1e-9 1e-9 1e-3 1e-3
} elseif {$paramset == "dsl_p1_u1"} { _Access_Params RACC 24e6 3.0e6 1e-8 1e-8 1e-3 1e-3
} elseif {$paramset == "dsl_p2_u2"} { _Access_Params RACC 18e6 1.5e6 1e-7 1e-7 1e-3 1e-3
} elseif {$paramset == "dsl_p3_u3"} { _Access_Params RACC 12e6 1.5e6 1e-7 1e-7 1e-3 1e-3
} elseif {$paramset == "dsl_p4_u4"} { _Access_Params RACC 6e6 1.0e6 1e-6 1e-6 1e-3 1e-3
} elseif {$paramset == "dsl_p5_u5"} { _Access_Params RACC 3e6 1.0e6 1e-6 1e-6 1e-3 1e-3
} elseif {$paramset == "dsl_p6_u6"} { _Access_Params RACC 6e6 1.0e6 1e-6 1e-6 1e-3 1e-3
} elseif {$paramset == "dsl_p7_u7"} { _Access_Params RACC 3e6 1.0e6 1e-6 1e-6 1e-3 1e-3
} elseif {$paramset == "core_only"} { _Access_Params RACC 1e9 1e9 1e-12 1e-12 0 0
} else {
error "ERROR: Invalid Net_Param name $paramset."
}
}
The next routines help to set network parameters for the core
# - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
# Set Global Vars for Access Link Parameters
# - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
proc _Core_Params {{numsw ""}
{Latency ""}
{Speed ""}} {
if {$numsw != ""} { gset NumCoreSW $numsw }
if {$Latency != ""} { gset CORE_Latency $Latency }
if {$Speed != ""} { gset CORE_Speed $Speed }
}
# - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
# Select a set of core parameters based on name
# - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
proc Set_Core_Params {paramset} {
# NumCoreSW Latency Speed
if {$paramset == "w1"} { _Core_Params 3 10e-3 1e9
} elseif {$paramset == "w2"} { _Core_Params 4 25e-3 1e9
} elseif {$paramset == "w3"} { _Core_Params 5 50e-3 1e9
} elseif {$paramset == "w4"} { _Core_Params 6 75e-3 1e9
} elseif {$paramset == "w5"} { _Core_Params 7 85e-3 1e9
} elseif {$paramset == "w6"} { _Core_Params 8 100e-3 1e9
} elseif {$paramset == "w7"} { _Core_Params 9 125e-3 1e9
} elseif {$paramset == "w8"} { _Core_Params 10 150e-3 1e9
} elseif {$paramset == "p1_u1"} { _Core_Params 3 10e-3 1e9
} elseif {$paramset == "p2_u2"} { _Core_Params 4 25e-3 1e9
} elseif {$paramset == "p3_u3"} { _Core_Params 5 50e-3 1e9
} elseif {$paramset == "p4_u4"} { _Core_Params 8 75e-3 1e9
} elseif {$paramset == "p5_u5"} { _Core_Params 10 100e-3 1e9
} elseif {$paramset == "p6_u6"} { _Core_Params 12 200e-3 1e9
} elseif {$paramset == "p7_u7"} { _Core_Params 15 250e-3 1e9
} elseif {$paramset == "core_only"} { _Core_Params 5 100e-3 1e9
} else {
error "ERROR: Invalid Net_Param name $paramset."
}
}
# - - - - - - - - - - - - - - - -
# Other Misc parameter settings
# - - - - - - - - - - - - - - - -
set CORESW_BufSizeBytes [expr 65*1518]
set DSLAM_BufSizeBytes [expr 65*1518]
set Firewall_BufSizeBytes [expr 65*1518]
set Modem_BufSizeBytes [expr 65*1518]
set RLAN_Speed 100E6
# - - - - - - - - - - - - - - - -
# Set Default Simulation length
# - - - - - - - - - - - - - - - -
set SimLengthSeconds [expr 10*60]
Share with your friends: |