Applicable Versions
NetSim StandardNetSim Pro


Applicable Releases
v12
v13


OLSR protocol implementation in NetSim is based on RFC 3626 (http://tools.ietf.org/html/rfc3626). This protocol is supported in NetSim for technologies such as MANET and WSN.

The Optimized Link State Routing Protocol (OLSR) is developed for mobile ad hoc networks.   It operates as a table-driven, proactive protocol, i.e., exchanges topology information with other nodes of the network regularly.  Each node selects a set of its neighbor nodes as "multipoint relays" (MPR).   In OLSR, only nodes, selected as such MPRs, are responsible for forwarding control traffic, intended for diffusion into the entire network.  MPRs provide an efficient mechanism for flooding control traffic by reducing the number of transmissions required.


Nodes that have been selected as multipoint relays by some neighbor node(s) announce this information periodically in their control messages. Thereby a node announces to the network, that it has reachability to the nodes which have selected it as an MPR.  In route calculation, the MPRs are used to form the route from a given node to any destination in the network.

 

Routing Table Calculation:

Each node maintains a routing table that allows it to route data, destined for the other nodes in the network.  The routing table is based on the information contained in the local link information base and the topology set. The route entries are recorded in the routing table in the following format:

1.  R_dest_addr     R_next_addr    R_dist   R_iface_addr

2.  R_dest_addr     R_next_addr    R_dist   R_iface_add

3.      ,,             ,,           ,,          ,,

Each entry in the table consists of R_dest_addr, R_next_addr, R_dist, and R_iface_addr.  Such entry specifies that the node identified by R_dest_addr is estimated to be R_dist hops away from the local node, that the symmetric neighbor node with interface address R_next_addr is the next-hop node in the route to R_dest_addr, and that this symmetric neighbor node is reachable through the local interface with the address R_iface_addr.

the routing table is updated when a change is detected in either:

 

      -    the link set,

 

      -    the neighbor set,

 

      -    the 2-hop neighbor set,

 

      -    the topology set,

 

      -    the Multiple Interface Association Information Base,


Please follow the steps given below to modify OLSR source codes to obtain log files: 


1. . Open NetSim Source codes using the open code button from Open Simulation->Workspace options 

2.  Add the following lines of code (highlighted in red) at the beginning of the OLSR_routing_Table.c file present in the ZRP project


#include "main.h"

#include "ZRP.h"

#include "ZRP_Enum.h"

//OLSR_log_hop count for 2 hop neighbour

int Hop_Count = 2;


3. The following function is defined at the end of the oLSR_routing_Table.c file



int fn_NetSim_OLSR_Route_Table_update_log(NETSIM_ID devid, char* filemode)

{

    sprintf(OLSR_Log_filename, "%s\\%s_OLSR_log.txt", pszIOLogPath, DEVICE_NAME(devid));

    OLSR_log_fp = fopen(OLSR_Log_filename, filemode);

    if (OLSR_log_fp && !strcmp(filemode, "w+"))

    {

        fprintf(OLSR_log_fp, "R_dest_addr, R_next_addr, R_dist, R_iface_addr");

        fclose(OLSR_log_fp);

    }

    else if (OLSR_log_fp && !strcmp(filemode, "a+"))

    {

        NODE_OLSR* olsr = GetOLSRData(pstruEventDetails->nDeviceId);

        OLSR_NEIGHBOR_SET* neighbor;

        OLSR_2HOP_NEIGHBOR_SET* two_hop_neighbor;

        OLSR_TOPOLOGY_INFORMATION_BASE* topology;

        NETSIM_IPAddress subnet = STR_TO_IP4("255.255.255.255");

        NETSIM_IPAddress R_dest_addr, R_next_addr, R_iface_addr;

        while (olsr->bRoutingTableUpdate)

        {

            //condition 2

            neighbor = olsr->neighborSet;

            while (neighbor)

            {

                if (neighbor->N_status >= SYM_NEIGH)

                {

                    R_dest_addr = olsr->linkSet->L_neighbor_iface_addr;

                    R_next_addr = olsr->linkSet->L_neighbor_iface_addr;

                    R_iface_addr = olsr->linkSet->L_local_iface_addr;

                    fprintf(OLSR_log_fp, "\n\n TIME(microsec) %f", pstruEventDetails->dEventTime);

                    fprintf(OLSR_log_fp, "\n %s, %s, %d, %s", (R_dest_addr)->str_ip, (R_next_addr)->str_ip, 1, (R_iface_addr)->str_ip);


                }

                neighbor = (OLSR_NEIGHBOR_SET*)LIST_NEXT(neighbor);

            }

            //Condition 3

            two_hop_neighbor = olsr->twoHopNeighborSet;

            while (two_hop_neighbor)

            {

                neighbor = olsrFindNeighborSet(olsr->neighborSet, two_hop_neighbor->N_2hop_addr);

                if (!neighbor && IP_COMPARE(two_hop_neighbor->N_2hop_addr, olsr->mainAddress))

                {

                    neighbor = olsrFindNeighborSet(olsr->neighborSet, two_hop_neighbor->N_neighbor_main_addr);

                    if (neighbor->N_willingness != WILL_NEVER && neighbor->N_status == MPR_NEIGH)

                    {

                        R_dest_addr = two_hop_neighbor->N_2hop_addr;

                        R_next_addr = two_hop_neighbor->N_neighbor_main_addr;

                        R_iface_addr = olsr->mainAddress;

                        fprintf(OLSR_log_fp, "\n\n TIME(microsec) %f", pstruEventDetails->dEventTime);

                        fprintf(OLSR_log_fp, "\n %s,%s,%d,%s", (R_dest_addr)->str_ip, (R_next_addr)->str_ip,Hop_Count, (R_iface_addr)->str_ip);

                    }

                }

                two_hop_neighbor = (OLSR_2HOP_NEIGHBOR_SET*)LIST_NEXT(two_hop_neighbor);

            }

            //Condition 3

            topology = olsr->topologyInfoBase;

            while (topology)

            {

                if (IP_COMPARE(R_dest_addr, topology->T_last_addr))

                {

                    if (IP_COMPARE(topology->T_dest_addr, olsr->mainAddress))

                    {

                        R_dest_addr = topology->T_dest_addr;

                        R_iface_addr = olsr->mainAddress;

                        fprintf(OLSR_log_fp, "\n\n TIME(microsec) %f", pstruEventDetails->dEventTime);

                        fprintf(OLSR_log_fp, "\n%s,%s,%d,%s", (R_dest_addr)->str_ip, (R_next_addr)->str_ip, Hop_Count + 1, (R_iface_addr)->str_ip);

                    }

                }

                topology = (OLSR_TOPOLOGY_INFORMATION_BASE*)LIST_NEXT(topology);

            }

            olsr->bRoutingTableUpdate = false;

            fclose(OLSR_log_fp);

        }

    }

    return 0;


}


4. The function calls (highlighted in red) to fn_NetSim_OLSR_Route_Table_update_log  are made in the function  fn_NetSim_OLSR_UpdateRoutingTable() as shown


int fn_NetSim_OLSR_UpdateRoutingTable()

{

    //Section 10

    NODE_OLSR* olsr=GetOLSRData(pstruEventDetails->nDeviceId);

    NETSIM_IPAddress subnet = STR_TO_IP4("255.255.255.255");

    OLSR_NEIGHBOR_SET* neighbor;

    OLSR_2HOP_NEIGHBOR_SET* two_hop_neighbor;

    OLSR_TOPOLOGY_INFORMATION_BASE* topology;

    if(!olsr->bRoutingTableUpdate)

    {

        return 0; //No update

    }

    //Condition 1

    olsrFlushroutingTable(olsr->ipWrapper,pstruEventDetails->nDeviceId);

    olsr->ipWrapper->table = NULL;

    //OLSR_Route_Log

    fn_NetSim_OLSR_Route_Table_update_log(pstruEventDetails->nDeviceId, "a+");

    //Condition 2

neighbor=olsr->neighborSet;

    while(neighbor)

    {

        if(neighbor->N_status>=SYM_NEIGH)

        {

            NETSIM_ID interfaceId = 1;

            iptable_add(olsr->ipWrapper,

                        neighbor->N_neighbor_main_addr,

                        subnet,

                        0,

                        neighbor->N_neighbor_main_addr,

                        1,

                        &olsr->mainAddress,

                        &interfaceId,

                        1,

                        "OLSR");

            //OLSR_Route_Log

            fn_NetSim_OLSR_Route_Table_update_log(pstruEventDetails->nDeviceId, "a+");

        }

        neighbor=(OLSR_NEIGHBOR_SET*)LIST_NEXT(neighbor);        

    }

    //Condition 3

    two_hop_neighbor=olsr->twoHopNeighborSet;

    while(two_hop_neighbor)

    {

        neighbor=olsrFindNeighborSet(olsr->neighborSet,two_hop_neighbor->N_2hop_addr);

        if(!neighbor && IP_COMPARE(two_hop_neighbor->N_2hop_addr,olsr->mainAddress))

        {

            neighbor=olsrFindNeighborSet(olsr->neighborSet,two_hop_neighbor->N_neighbor_main_addr);

            if(neighbor->N_willingness != WILL_NEVER && neighbor->N_status==MPR_NEIGH)

            {

                NETSIM_ID interfaceId = 1;

                iptable_add(olsr->ipWrapper,

                            two_hop_neighbor->N_2hop_addr,

                            subnet,

                            0,

                            two_hop_neighbor->N_neighbor_main_addr,

                            1,

                            &olsr->mainAddress,

                            &interfaceId,

                            2,

                            "OLSR");

                //OLSR_Route_Log

                fn_NetSim_OLSR_Route_Table_update_log(pstruEventDetails->nDeviceId, "a+");

            }

        }

        two_hop_neighbor=(OLSR_2HOP_NEIGHBOR_SET*)LIST_NEXT(two_hop_neighbor);

     }

    //Condition 3

    topology=olsr->topologyInfoBase;

    while(topology)

    {

        ptrIP_ROUTINGTABLE table=iptable_check(&olsr->ipWrapper->table,topology->T_dest_addr,subnet);

        if(!table && IP_COMPARE(topology->T_dest_addr,olsr->mainAddress))

        {

            table=iptable_check(&olsr->ipWrapper->table,topology->T_last_addr,subnet);

            if(table && table->Metric < olsr->nZoneRadius)

            {

                NETSIM_ID interfaceId;

                iptable_add(olsr->ipWrapper,

                            topology->T_dest_addr,

                            subnet,

                            0,

                            table->gateway,

                            1,

                            &olsr->mainAddress,

                            &interfaceId,

                            table->Metric + 1,

                            "OLSR");

                //OLSR_Route_Log

                fn_NetSim_OLSR_Route_Table_update_log(pstruEventDetails->nDeviceId, "a+");

                topology=olsr->topologyInfoBase;

                continue;

            }

        }

        topology=(OLSR_TOPOLOGY_INFORMATION_BASE*)LIST_NEXT(topology);        

    }

    olsrUpdateIptable(olsr->ipWrapper->table,pstruEventDetails->nDeviceId);

    olsr->bRoutingTableUpdate=false;

    if(DEVICE_NWLAYER(pstruEventDetails->nDeviceId)->nRoutingProtocolId == NW_PROTOCOL_ZRP)

        fn_NetSim_BRP_Update(olsr->ipWrapper->table);

    return 0;

}


5. The following lines of code (highlighted in red) are added to the OLSR.h file present in the ZRP project

#ifdef  __cplusplus

extern "C" {

#endif

#define NW_PROTOCOL_NDP NW_PROTOCOL_OLSR

    //OLSR DEVICE LOG

    FILE* OLSR_log_fp;

    char OLSR_Log_filename[BUFSIZ];

//Config parameter


6. The following lines of code are added in fn_NetSim_ZRP_Init() present in ZRP.c file 


_declspec (dllexport) int fn_NetSim_ZRP_Init(struct stru_NetSim_Network *NETWORK_Formal,

    NetSim_EVENTDETAILS *pstruEventDetails_Formal,

    char *pszAppPath_Formal,

    char *pszWritePath_Formal,

    int nVersion_Type,

    void **fnPointer)

{

    fn_NetSim_ZRP_Init_F();

    for (int i = 0; i < NETWORK->nDeviceCount; i++)

    {

        NODE_OLSR* olsr = GetOLSRData(pstruEventDetails->nDeviceId);

        if (olsr)

            fn_NetSim_OLSR_Route_Table_update_log(i + 1, "w+");

    }

    return 0;

}


Note: In v12.2 and v13, comment the following return statement in the  fn_NetSim_ZRP_Init() 

//return fn_NetSim_ZRP_Init_F();

7. After modifying the source codes as explained above, right-click on the ZRP project and select rebuild. Ensure that you have set the platform settings in Visual studio to win32/x64 as per the build of NetSim that you have installed, before building. 

8. Upon successful build, running simulations involving MANET protocol will generate individual log files for each node which can be accessed from the results dashboard as shown below: 


Individual log files contain the route table entries of a specific node at different points of simulation time along with time stamps 




Related articles:

https://support.tetcos.com/support/solutions/articles/14000113349-understanding-olsr-route-discovery-procedure-using-route-table-logs/preview