Details of the parser
Simulating a computer network implies simulating more than one end host. However, the network stacks in operating systems are only designed for the computer they are running on. Modifications are necessary to allow multiple instances of each network stack to run in tandem.
The simplest way to achieve this is have each instance in a different process
by using fork(). As the network stacks are now contained in shared libraries,
loading a new instance of the shared library for each instantiation of a
stack would also solve this problem. The big problem with both these methods
is efficiency and scalability.
One of the goals of NSC is to have only a small extra cost in efficiency so the NSC stacks can be used to simulate the same scenarios as ns-2's current protocol implementations. It should be possible to simulate thousands of network stacks in reasonable time. The approach described above does not meet this goal.
This problem and its solution is documented well in the publication Network Simulation Cradle in section 3.4. To paraphrase: the problem with the network stacks is that they are not re-entrant. To allow multiple instances to run, they each need their own version of all the global variables.
It is possible to programmatically replace all global variables and all references to global variables in C source code. This is the function of the badly named "C parser".
The parser reads in a file of global variables to change, reads source code
from stdin and outputs the modified source code to stdout. It is a fairly
complaint C parser that is designed to take input from the gcc preprocessor
invoked by gcc -E. Both global variable and static local variables are able
to be modified.
An example of input and output in the initial version of the C parser is as follows:
Before:
struct ifaddr ifaddr;
void my_function()
{
ifaddr.member = 0;
After:
struct ifaddr global_ifaddr[NUM_STACKS];
void my_function()
{
global_ifaddr[get_stack_id()].member = 0;
This is the basic premise of the parser, though it has become more complicated with variable substitutions. The exact details of the problems faced may be presented in a later publication.
The parser has been well tested: it can run over the FreeBSD, OpenBSD and Linux kernels.
The parser is available for download.