5 Design and Implementation
5.1 Kernel Modification
The NCTUns network simulator is based on a new simulation methodology -- the kernel re-entering simulation methodology. It uses an existing real-world FreeBSD/Linux protocol stack to provide high-fidelity TCP/IP network simulation results. The Figute5.1.1 helps to illustrate this concept.[21]
Figure 5.1.1 The kernel re-entering simulation methodology Simulation Engine
TCP sender
TCP receiver link
TCP/IP protocol stack
Tunnel Interface 2 Tunnel
Interface 1
user level kernel level
According to the description of [21], when a process was forked by the simulation engine, the simulation engine uses system call to store the simulated node id into the process handler. This information allows the kernel to know whether a process is used by a simulation or not. The structure task_struct is modified as below:
struct task _struct {
/* record the process belongs to which node */
unsigned int p_node;
/* record the process belongs to which node */
unsigned int p_node;
//NCTUNS }
If a process creates an INET socket such as TCP, UDP, RAW socket, we should also register the node id into the corresponding INET socket structure, which is structure sock.
unsigned short sk _vport; /* virtual port number */
struct pmap *pmap; /* point to port mapping information */
//NCTUNS
unsigned short sk _vport; /* virtual port number */
struct pmap *pmap; /* point to port mapping information */
//NCTUNS }
For the datagram INET socket such as UDP and RAW socket, we store the node id into the INET socket structure (sock) when a process calls the socket() system call:
Asmlink age long sys_sock et (int family, int type, int protocol) {
int retval;
struct sock et *sock ;
retval = sock _create(famil y, type, protocol, &sock );
… //NCTUNS
/* If current process belongs to a simulation, we should store node id into sk . */
if (current->p_node > 0) {
sock ->sk ->nodeID = current ->p_node;
} else {
sock ->sk ->nodeID = 0;
sock ->sk ->sk _vport = 0;
} //NCTUNS
… }
Asmlink age long sys_sock et (int family, int type, int protocol) {
int retval;
struct sock et *sock ;
retval = sock _create(famil y, type, protocol, &sock );
… //NCTUNS
/* If current process belongs to a simulation, we should store node id into sk . */
if (current->p_node > 0) {
sock ->sk ->nodeID = current ->p_node;
} else {
sock ->sk ->nodeID = 0;
sock ->sk ->sk _vport = 0;
} //NCTUNS
… }
With the node id information, we can correctly translate the IP address in the kernel. For more details of the S.S.D.D address format, readers can refer [21] and [20].
Besides, according to this information, kernel can determine whether the port number translation has to be done or not. The port number translation is a mechanism to translate a real port number to a virtual port number. [20][21] Additionally, nodeID and p_node are also used to identify whether the timer of this execution is based on a virtual-time timer or not. After realizing above short descriptions about how the kernel is modified, this will lead us further into the consideration of new design for our requirements.
Like other traffic generators, Node Control Program is also a process forked by the simulation, and one of its jobs is to deliver god information between the Node and the simulator engine. Another objective is to control the node’s behavior. During simulation, all information, such as node’s location, speed, angle and so on, is keep in the simulation engine; hence, Node Control Program has to use IPC to obtain these information. Here, we adopt the UNIX socket as our choice, because it is easy to expand and debug.
Besides, Node Control Program is also responsible for communicating with
other node’s Node Control Program. As original traffic generator in simulation, this kind of communication is based on virtual clock, because it is used to simulate tactical Ad Hoc network communication instead of acquiring god information between them.
Figure 5.1.2 Two types communication of Node Control Program
Figure 5.1.2 clearly shows the difference of communication between these two types. The shading broken arrow in figure 5.1.2 is used to communicate between Node Control Programs, and black arrow is used to communicate god information between Node Control Program and simulation engine.
The question now arise: Node Control Program is a child process which was forked by the simulation engine, as we mentioned ahead, results in that all socket executes on Node Control Program will based on virtual time and IP address and port number will be translated as previously described. Therefore, the communication
Simulation Engine
between Node Control Program and simulation engine can’t work correctly. The reason is that the communication between them is based on general IPC socket and its IP address is local loopback address instead of our IP address format, but all packets’
address will be translated into S.S.D.D format. Due to the modified address and port number, packets cannot correctly reach its destination.
The solution of this problem is to clean nodeID we mark in kernel by calling system call sys_NCTUNS_misc. In order to achieve this, we add another system call sys_NCTUNS_cancel_socknodeID to erase it if we want to create the socket whose IP address is not S.S.D.D format and based on real time clock.
The sys_NCTUNS_misc system call with parameter NSC_REGPID is used to enable the process that is forked by the simulation engine to know that it belongs to which simulated node. In opposition to sys_NCTUNS_misc system call, sys_NCTUNS_cancel_socknodeID is used to cancel the nodeID which was set by
asmlinkage int sys_NCTUNS_cancel_socknodeID(int fd)
sys_NCTUNS_misc.
Besides, we extend the functionality of system call sys_NCTUNS_misc with parameter NSC_PIDTONID to let Node Control Program acquire its node id according to the process id.