**National Institute of Standards & Technology**

**Gaithersburg, Maryland**

June 30, 2001

**NIST AODV OPNET Model**

***Programming Reference***

*Written*

*By*

Lyes Guemari

Guest Researcher

**[Table of content]{.smallcaps}**

[I. [Introduction]{.smallcaps} 3](#i.-introduction)

[[II. State variables]{.smallcaps} 3](#ii.-state-variables)

[Routing Table 3](#routing-table)

[Request Sent Repository 3](#request-sent-repository)

[Request Seen Repository 4](#request-seen-repository)

[Successor Table 4](#successor-table)

[Ack Pending List 4](#ack-pending-list)

[Transmission Window Table 4](#transmission-window-table)

[[III. Discovery Package]{.smallcaps} 5](#iii.-discovery-package)

[aodv_initiate_discovery 5](#aodv_initiate_discovery-int-dest)

[aodv_continue_discovery 5](#aodv_continue_discovery-int-dest)

[aodv_terminate_discovery 5](#aodv_terminate_discoveryint-dest)

[aodv_rreq_pk_receive 5](#aodv_rreq_pk_receivepacket-rreq_pk_ptr)

[aodv_is_req_fresh_enough
5](#aodv_is_req_fresh_enoughpacket-rreq_pk_ptr)

[aodv_update_or_create_reverse_entry
5](#aodv_update_or_create_reverse_entrypacket-rreq_pk_ptr)

[aodv_rrep_pk_generate_from_destination
6](#aodv_rrep_pk_generate_from_destinationpacket-rreq_pk_ptr)

[aodv_gratuitous_rrep_pk_generate
6](#aodv_gratuitous_rrep_pk_generatepacket-rreq_pk_ptr)

[aodv_rrep_pk_generate_from_relay
6](#aodv_rrep_pk_generate_from_relaypacket-rreq_pk_ptr)

[aodv_rreq_pk_forward 6](#aodv_rreq_pk_forwardpacket-rreq_pk_ptr)

[aodv_rrep_pk_receive 6](#aodv_rrep_pk_receivepacket-pk_ptr)

[aodv_cancel_pending_request 6](#aodv_cancel_pending_request-int-dest)

[[IV. Maintenance Package]{.smallcaps} 7](#iv.-maintenance-package)

[aodv_rerr_pk_receive 7](#aodv_rerr_pk_receivepacket-rerr_pk_ptr)

[aodv_rerr_pk_process 7](#aodv_rerr_pk_processpacket-rerr_pk_ptr)

[aodv_non_delete_rerr_pk_process
7](#aodv_non_delete_rerr_pk_processpacket-rerr_pk_ptr)

[aodv_rerr_pk_generate
7](#aodv_rerr_pk_generateint-dest_ip_addr-int-err_case)

[aodv_generate_non_delete_rerr_pk
8](#aodv_generate_non_delete_rerr_pkint-dest_ip_addr)

[aodv_initiate_maintenance
8](#aodv_initiate_maintenanceint-dest-int-source)

[aodv_flag_lost_entries
8](#aodv_flag_lost_entriesint-node_downstream-int-final_destination)

[aodv_hello_interval_extend 8](#aodv_hello_interval_extend)

[aodv_maintain_local_conn 8](#aodv_maintain_local_connint-previous_hop)

[[V. Data **t**ransmission Package]{.smallcaps}
9](#v.-data-transmission-package)

[aodv_data_pk_receive_from_mac
9](#aodv_data_pk_receive_from_macpacket-pk_ptr)

[aodv_data_pk_receive_from_appl
9](#aodv_data_pk_receive_from_applpacket-pk_ptr)

[aodv_data_pk_queue 9](#aodv_data_pk_queue-packet-pk_ptr)

[aodv_data_pk_queue_head 9](#aodv_data_pk_queue_head-packet-pk_ptr)

[aodv_data_pk_dequeue 9](#aodv_data_pk_dequeue-int-index)

[aodv_data_pk_dequeue_tail 9](#aodv_data_pk_dequeue_tail-int-index)

[aodv_ack_timeout_schedule
10](#aodv_ack_timeout_schedulepacket-data_pk_ptr)

[[VI. Buffer Package]{.smallcaps} 10](#vi.-buffer-package)

[aodv_buffer_drop 10](#aodv_buffer_drop-int-index)

[aodv_buffer_empty 10](#aodv_buffer_empty-int-index)

[aodv_buffer_serve 10](#aodv_buffer_serve-int-index)

[aodv_buffer_size 10](#aodv_buffer_size-int-index)

[[VII. Miscelleanous]{.smallcaps} 10](#vii.-miscellaneous)

[aodv_pk_send 10](#aodv_pk_sendpacket-pk_ptr-int-next_hop)

[aodv_prg_add_prec 11](#aodv_prg_add_precint-prec-int-dest)

[aodv_prg_remove_prec 11](#aodv_prg_remove_precint-prec-int-dest)

[aodv_prg_add_successor 11](#aodv_prg_add_successorint-dest-int-prec)

[aodv_prg_remove_from_prec_lists
11](#aodv_prg_remove_from_prec_listsint-prec)

[aodv_prg_print_entry 11](#aodv_prg_print_entryint-dest-int-trace_lev)

[aodv_prg_print_path
12](#aodv_prg_print_pathint-src-int-dest-int-trace_lev)

[aodv_prg_print_rt 12](#aodv_prg_print_rtint-trace_lev)

[aodv_print_major 12](#aodv_print_majorchar-msg-int-trace_level)

[aodv_print_minor 12](#aodv_print_minorchar-msg-int-trace_level)

# [I. [Introduction]{.smallcaps}]{.underline}

The present document serves as a reference for the NIST/AODV OPNET
Model, which is downloadable from the Wireless Communication
Technologies Group website -- <http://w3.antd.nist.gov/wctg>.

This document makes a listing of the state variables and the primary
functions that are directly invoked from within the AODV Routing
Process. The functions are commonly classified either according to the
context they operate in (discovery, maintenance, etc) or to the object
they attempt to manipulate (data packet, reply packet, data, buffer,
etc).

For instance, the function that returns the size of the data (send)
buffer, will be called aodv_buffer_size(...).

# [[II. State variables]{.underline}]{.smallcaps}

## Routing Table

*Declaration*

Aodv_Route_Table_Stat my_route_table;

*Description*

A routing table in the context of our model is nothing but a simple
array of N_MAX routing table entries. Although this approach may seem a
bit to rigid (as the number of total entries "N_MAX" that can be held in
the routing table has to be fixed once for all before the compilation),
it provides a better performance when it comes to simulation times for
relatively larger networks.

For more information, you can refer to the "Aodv_Route_Table_Stat" and
"Aodv_Route_Table_Entry" external files.

Note: In the following sections, the constant N_MAX refers to the
maximum number of nodes within the simulated network.

## Request Sent Repository

*Declaration*

Aodv_Req_Sent_Attr req_sent_rep\[N_MAX\];

*Description*

Each time a RREQ is generated by a node, the latter keeps a record of it
in its request sent repository.

For instance, if the current node generates a RREQ for a destination
"i", then req_sent_rep\[i\] will hold all the needed information incase
of an eventual rebroadcast. These information include a copy of the RREQ
packet itself, a counter of the total number of retries, and a
RREP_WAIT_TIME timer (if no reply is received for a given destination
within a RREP_WAIT_TIME period of time, then the current node should
rebroadcast a RREQ for that same destination).

## Request Seen Repository

*Declaration*

Aodv_Req_Seen_Attr req_seen_rep\[N_MAX\];

*Description*

Each node keeps records of all the broadcast RREQ that it receives.
Thus, req_seen_rep\[i\] potentially contains the Broadcast ID and the
reception time of the last received received RREQ from the node "i".

## Successor Table

*Declaration*

Aodv_List \* successor_table;

*Description*

Each time a node \"A\" is added to the list of precursor of a given
destination \"B\", a function is indirectly called to add \"B\" to the
list of nodes to which \"A\" is a precursor. Thus, when the link to A is
no longer available and node wants to expunge it from its routing table,
node has only to process entries that are listed within the successor
list of \"A\".

## Ack Pending List

*Declaration*

Aodv_List \* ack_pending_list;

*Description*

This list holds the data packets that are waiting for acknowledgments.
Each entry contains a copy of the data packet and an ACK_WAIT_TIME
timer. If no ack is received within this period of time, the node should
rebroadcast the data packet.

## Transmission Window Table

*Declaration*

int trans_window_locked\[N\];

*Description*

When a packet is sent to a next hop node "i", the transmission window is
immediately locked (trans_window_locked\[i\] is set to 1). The window is
released as soon as the next hop acknowledges the data packet.

# [[III. Discovery Package]{.underline}]{.smallcaps}

## aodv_initiate_discovery (int dest)

Arguments dest Destination IP address of the requested node.

Return Value void

Description Initiates the discovery service for a given destination.

## aodv_continue_discovery (int dest)

Arguments dest Destination IP address of the requested node.

Return Value void

Description Rebroadcast a request for a given destination. This function
is called when no reply was received for the previous request and there
is still a possibility to renew it.

> An expanded ring search method is automatically used here.

## aodv_terminate_discovery(int dest)

Arguments dest Destination IP address of the requested node.

Return Value void

Description This procedure is called when the discovery process has
arrived to an end, and no reply was received. The node, then, drops the
data buffer and resets the request record within the request sent
repository.

## aodv_rreq_pk_receive(Packet\* rreq_pk_ptr)

Arguments rreq_pk_ptr Pointer to the received RREQ packet.

Return Value void

Description This routine receives the aodv RREQ packet from the lower
layer and decides whether the node should process the packet, discard it
or simply forward it.

## aodv_is_req_fresh_enough(Packet\* rreq_pk_ptr)

Arguments rreq_pk_ptr Pointer to the received RREQ packet.

Return Value Boolean

Description Check whether the BroadcastID of the request is greater than
the last seen. If so, RREQ is automatically processed, and the RREQ is
recorded in the req_seen_rep. Else, node checks whether RREQ packet was
seen less than RECORD_BROADCAST_TIME seconds ago. If so, RREQ must be
discarded. Else, it is processed.

## aodv_update_or_create_reverse_entry(Packet\* rreq_pk_ptr)

Arguments rreq_pk_ptr Pointer to the received RREQ packet.

Return Value void

Description This routine decides whether to create or update a reverse
entry following the reception of a RREQ packet.

> RREQs which turn out to be hello messages (RREQ.dest = RREQ.source)
> are treated differently.

## aodv_rrep_pk_generate_from_destination(Packet\* rreq_pk_ptr)

Arguments rreq_pk_ptr Pointer to the received RREQ packet.

Return Value void

Description This function is called when a RREQ has reached its
destination and node wants to reply. Once the RREQ packet is generated,
the procedure unicast it back to the node upstream (node from which RREQ
was received) (PreviousHop field).

## aodv_gratuitous_rrep_pk_generate(Packet \* rreq_pk_ptr)

Arguments rreq_pk_ptr Pointer to the received RREQ packet.

Return Value void

Description Generate a gratuitous RREP and unicast it to the destination
node (node for which RREQ was originally generated).

## aodv_rrep_pk_generate_from_relay(Packet\* rreq_pk_ptr)

Arguments rreq_pk_ptr Pointer to the received RREQ packet.

Return Value void

Description This routine is called when an intermediate node receives a
RREQ an has fresh enough route to generate a RREP for the requested
destination.

## aodv_rreq_pk_forward(Packet\* rreq_pk_ptr)

Arguments rreq_pk_ptr Pointer to the received RREQ packet.

Return Value void

Description Node does not have a fresh enough entry (or does not have an
entry at all) to answer the received RREQ, so it decides to forward it.
Node increments the Hop Count field and decrements the TTL field.

> Note that packet is sent to the MAC layer only if TTL \> 0.

## aodv_rrep_pk_receive(Packet\* pk_ptr)

Arguments pk_ptr Pointer to the received RREP packet.

Return Value void

Description This routine receives the aodv RREP packet from the lower
layer and decides whether the node should process the packet or simply
forward it.

## aodv_cancel_pending_request( int dest)

Arguments dest Destination IP address of the requested node.

Return Value void

Description This routine is called to cancel a pending request for a
given destination. Obviously, this means that a reply was received for
that same destination.

# [[IV. Maintenance Package]{.underline}]{.smallcaps}

## aodv_rerr_pk_receive(Packet\* rerr_pk_ptr)

Arguments rerr_pk_ptr Pointer to the received RERR packet.

Return Value void

Description This routine is called to redirect the received RERR packet.
In fact, different functions are called according the fact that the N
flag is set or not.

## aodv_rerr_pk_process(Packet\* rerr_pk_ptr)

Arguments rerr_pk_ptr Pointer to the received RERR packet.

Return Value void

Description This routine receives regular RERR packets ( N flag set to
0). When such a packet is received, node effectively processes it, only
if the previous hop is the next hop toward the unreachable destination
(this is done for each destination included in the list of unreachable
destinations of the RERR packet). If so, invalidates the entry with the
new sequence number and checks the precursor list of the entry. If it is
empty, destination is removed from the list of unreachable destinations.
Else, it remains there. If at least one destination is still in the list
of unreachable destinations, then the RERR is rebroadcast. In the other
case, RERR is destroyed.

## aodv_non_delete_rerr_pk_process(Packet\* rerr_pk_ptr)

Arguments rerr_pk_ptr Pointer to the received RERR packet.

Return Value void

Description This routine receives the RERR packets whose N flag is set.
When such a packet is received, node effectively processes it, only if
the previous hop is the next hop toward the unreacheable destination
(the one included in the list of unreachable destinations of the RERR
packet). If so, the current node checks the precursor list of the entry
corresponding to the unreachable destination.

> If it is empty, RERR has reached the source node. The latter initiates
> a discovery service in order to update its entry for the repaired
> destination.
>
> Else, if the precursor list is not empty, then node simply forwards
> the RERR.
>
> In all other cases, RERR is destroyed.

## aodv_rerr_pk_generate(int dest_ip_addr, int err_case)

Arguments dest_ip_addr Destination IP address of the lost node.

err_case Error case (see below)

Return Value void

Description This routine is called whenever a node needs to generate a
RERR packet. This could happened in three cases:

> Case (i) the link with the node upstream has broken and no repair was
> attempted.
>
> Case (ii) the node has received a packet for which it does not have a
> route. RERR packet generation is different according the case.
>
> Case (iii) fail to repair a specific destination. the difference
> between this case and case (i) is that node does not to be invalidated
> as it already has been.

## aodv_generate_non_delete_rerr_pk(int dest_ip_addr)

Arguments dest Destination IP Address of the lost node.

Return Value void

Description This routine is called when an entry is repaired with a
different length (hop count). In this case, generates a RERR packet with
the N flag set. The RERR packet includes the repaired destination IP
address and its sequence number.

## aodv_initiate_maintenance(int dest, int source)

Arguments dest Destination IP Address of the lost node.

> Source Destination IP address of the source node (along the broken
> route).

Return Value void

Description This routine is called when a route breaks and node wants to
attempt a local repair to restore it.

## aodv_flag_lost_entries(int node_downstream, int final_destination)

Arguments node_downstream Destination IP Address of the lost node.

> final_destination Destination IP address of the final destination
> along the broken route).

Return Value void

Description This procedure is called when the node up stream an active
link is lost. In this case, and if the REPAIR mode is enabled, then node
flags all the other destinations that have been lost because of the link
breakage before it attempts to repair the route for the final
destination.

## aodv_hello_interval_extend ()

Arguments No arguments.

Return Value void

Description This routine invalidates the current hello interruption if
any, and schedules a new interruption for the next hello interval.

## aodv_maintain_local_conn(int previous_hop)

Arguments previous_hop Source IP address as indicated in the IP header
of the received broadcast packet.

Return Value void

Description This routine is called whenever a broadcast is received (to
the exception of Hello messages). The idea is to update the previous hop
entry in the routing table. The previous hop is the node that last
broadcast the packet.

# [[V. Data transmission Package]{.underline}]{.smallcaps}

## aodv_data_pk_receive_from_mac(Packet\* pk_ptr)

Arguments pk_ptr Pointer to the received data packet.

Return Value void

Description This routine handles the incoming data packets from the MAC
layer (this excludes data packet that are not destined for the current
node): If a route is already available, the packet is immediately sent
to the next hop destination. Else, this routine destroys the packet and
broadcasts a RERR message to the neighboring nodes.

## aodv_data_pk_receive_from_appl(Packet\* pk_ptr)

Arguments pk_ptr Pointer to the received data packet.

Return Value void

Description This routine takes the upcoming data packet in charge: If a
route is already available, the packet is immediately sent to the next
hop destination. Else, this routine initiates a route discovery service
if none is pending for that same destination.

> Note that this routine processes only data packets arriving from the
> internal source.

## aodv_data_pk_queue (Packet\* pk_ptr)

Arguments pk_ptr Pointer to the data packet to queue.

Return Value void

Description Queue the given data packet into the appropriate buffer. The
buffer whose index corresponds to the packet destination.

## aodv_data_pk_queue_head (Packet\* pk_ptr)

Arguments pk_ptr Pointer to the data packet to queue.

Return Value void

Description Queue the given data packet in the first position of the
corresponding buffer.

## aodv_data_pk_dequeue (int index)

Arguments index Index of the sub-queue from which a packet should be
dequeued.

Return Value Packet\*

Description Returns the first packet (first in) from the indicated data
buffer.

## aodv_data_pk_dequeue_tail (int index)

Arguments index Index of the sub-queue from which a packet should be
dequeued.

Return Value Packet\*

Description Returns the last packet (last in) from the indicated data
buffer.

## aodv_ack_timeout_schedule(Packet\* data_pk_ptr)

Arguments data_pk_ptr Pointer to the just sent data packet.

Return Value void

Description This routine is called when a data packet is sent to the MAC
Layer. Specifically, this procedure schedules an interrupt to occur
after Wait_Ack seconds. If no ack is received within this period of
time, the process transits to the Ack_Timeout State in order to
retransmit the lost packet.

> However, if an ack is received, the ack-timeout interrupt is cancelled
> (see Rcv_Ack State).

## [[VI. Buffer Package]{.underline}]{.smallcaps}

## aodv_buffer_drop (int index)

Arguments index Index of the sub-queue.

Return Value void

Description Flushes the corresponding buffer if it is not empty

## aodv_buffer_empty (int index)

Arguments index Index of the sub-queue.

Return Value Boolean

Description Returns OPC_TRUE if buffer is empty OPC_FALSE otherwise.

## aodv_buffer_serve (int index)

Arguments index Index of the sub-queue.

Return Value void

Description This routine is called whenever an entry is created or
restored. It de-queues the first packet in the sub-queue, and routes it
to its destination.

## aodv_buffer_size (int index)

Arguments index Index of the sub-queue.

Return Value int

Description Returns the number of data packets waiting for this
destination.

# [[VII. Miscellaneous]{.underline}]{.smallcaps}

## aodv_pk_send(Packet\* pk_ptr, int next_hop)

Arguments pk_ptr Pointer to the packet to send to the MAC layer.

next_hop Destination IP address (as in the IP header) of the packet (-1
if it is a broadcast).

Return Value void

Description This routine sends the aodv packet to the lower Layer
indicating its next hop destination through an ICI. The \"IP Header\"
(nextHop and previousHop) fields are set by this routine. Route
utilization records are also maintained at this point.

## aodv_prg_add_prec(int prec, int dest)

Arguments prec Destination IP address of the precursor.

dest Destination IP address of the target node for which prec is a
precursor.

Return Value Boolean

Description Add the node \"prec\" to the precursor list of the given
entry \"dest\".

> Note that the precursor node is inserted in a sub-list whose index
> equals to its destination IP address. This makes it easier to remove
> the node if it is eventually lost.

## aodv_prg_remove_prec(int prec, int dest)

Arguments prec Destination IP address of the precursor.

dest Destination IP address of the target node for which prec is a
precursor.

Return Value void

Description Remove the node \"prec\" from the precursor list of the
given entry \"dest\".

## aodv_prg_add_successor(int dest, int prec)

Arguments dest Destination IP address of the target node for which prec
is a precursor.

prec Destination IP address of the precursor.

Return Value void

Description Each time a node \"A\" (prec) is added to the list of
precursor of a given destination \"B\" (dest), this function is called
to add \"B\" in the list of nodes to which \"A\" is a precursor. Thus,
when link to A is no longer available and node wants to expunge it from
its routing table, node has only to process entries that are listed
within the successor list of \"A\".

## aodv_prg_remove_from_prec_lists(int prec)

Arguments prec Destination IP address of the lost node.

Return Value void

Description When a node \"A\" (prec) is no longer available, the current
function is called to remove it from any precursor list within the
routing table. To do so, the function reads the entry corresponding to
the node \"A\" within the \"reverse precursor list\" and gets the list
of entries where \"A\" is a precursor. It then goes through all these
entries and removes the lost node from their precursor lists.

## aodv_prg_print_entry(int dest, int trace_lev)

Arguments dest IP address of the entry to print.

trace_lev Priority of the current printing.

Return Value void

Description Prints the routing table entry for the given destination.

## aodv_prg_print_path(int src, int dest, int trace_lev)

Arguments dest IP address of the entry to print.

trace_lev Priority of the current printing.

Return Value void

Description Prints the path between a source and a destination.

## aodv_prg_print_rt(int trace_lev)

Arguments trace_lev Priority of the current printing.

Return Value void

Description Prints the routing table of the current node.

## aodv_print_major(char \* msg, int trace_level)

Arguments msg Pointer to the message to print.

trace_lev Priority of the current printing.

Return Value void

Description Prints a major message (with complete header: current node
address, current time, etc).

## aodv_print_minor(char \* msg, int trace_level)

Arguments msg Pointer to the message to print.

trace_lev Priority of the current printing.

Return Value void

Description Prints a minor message (no header).