<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 3.2//EN">
<html>
<head>
   <title>OMNEST/OMNeT++ INET Framework - A Walkthrough</title>
   <meta name="Author" content="Andras Varga">
   <link href="opp.css" rel="stylesheet" type="text/css">
</head>

<body>

<center style="background-color:#005e77; color:#ffffff; border:1px solid">
<h1><font size="+2">INET Framework for OMNEST/OMNeT++</font></h1>
<p><font size="+2"><i>A Guided Tour</i></font></p>
</center>

<h3>Contents</h3>
<ul>
<a href="#intro">Introduction</a><br>
<a href="#launching">Launching the ARPTest simulation</a><br>
<a href="#gui">The GUI at the first glance</a><br>
<a href="#running">Let's run the simulation!</a><br>
<a href="#restart">Over? You can restart it!</a><br>
<a href="#linkcolors">OK, but what are those flashing link colors?</a><br>
<a href="#inside">What is inside the hosts and routers?</a><br>
<a href="#steps">Steps towards exploring ARP</a><br>
<a href="#arpbegins">ARP begins</a><br>
<a href="#requestpacket">The ARP Request packet</a><br>
<a href="#pendingqueue">The pending queue</a><br>
<a href="#arpcache">The ARP cache</a><br>
<a href="#transmission">Transmission over Ethernet</a><br>
<a href="#arpreply">ARP Reply</a><br>
<a href="#procreply">Processing the ARP Reply</a><br>
<a href="#syn">The client's SYN gets to the server</a><br>
<a href="#discovering">Following ARP from the documentation</a><br>
<a href="#conclusion">Conclusion</a><br>
</ul>

<a name="intro"/><h3>Introduction</h3>

<p>
The purpose of this tutorial is to get you familiar with the INET framework,
a simulation model suite for TCP/IP and Internet-related protocols,
written for the OMNeT++/OMNEST simulation environment.
</p>

<p>
This tutorial is based on the ARPTest example simulation. To try it, you need
a binary (executable) version of this simulation. The easiest is to download
and install the Windows demo for INET. Alternatively (or if your platform is
Linux or some other OS), you may download and compile the OMNeT++ and
INET source packages.
</p>

<a name="launching"/><h3>Launching the ARPTest simulation</h3>

<p>
When you start the INET demo package (if you installed the Windows demo, you'll
find the INET demo on the Start Menu; if you compiled INET yourself, find and
run Examples/rundemo[.bat]), you'll see a window like this:
</p>

<p class="img"><a href="images/rundemo2.gif"><img src="thumbs/rundemo2.gif"/></a></p>

<p>
Click the button which says "ARP Test" on the left -- a description of the model
should appear in the main window. Click the large "Launch" button on the bottom,
and the ARP simulation model should start.
</p>

<a name="gui"/><h3>The GUI at the first glance</h3>

<p>
The picture you see will look like this.
</p>

<p class="img"><a href="images/arptest.gif"><img src="thumbs/arptest.gif"/></a></p>

<p>
The window in the back is the main OMNeT++/OMNEST window, closing it will exit
the program. The large text window on the right side displays log messages
from the simulation model (output from <tt>ev &lt;&lt;</tt> statements
in the C++ code will write there), and the left-hand displays the model
objects in a foldable tree form. There's a 3-line status bar at the top
(we'll look at it later), and a toolbar to access frequently used functions
of the GUI.
</p>

<p>
The front window displays the simulation model. If you happen to accidentally
close it, you can open it again by clicking the "Inspect network" toolbar icon.
</p>

<p class="img"><img src="images/tb-inspectnet.gif"/></p>

<a name="running"/><h3>Let's run the simulation!</h3>

<p>
Click on the "Run" button on the main window's toolbar, or hit F5.
</p>

<p class="img"><img src="images/tb-run.gif"/></p>

<p>
First you should see messages labelled "autoconf" being exchanged by the nodes,
as part of the Ethernet model autoconfiguration process:
</p>

<p class="img"><img src="images/autoconfmsg.gif"/></p>

<p>
Then, at about 1ms simulation time, autoconfig finishes, and simulating
the network operation begins. In the model scenario, the client computer
(laptop icon) opens a TCP connection to the server (server icon) at 1s,
and starts sending a large data stream. The server will just echo the data
sent by the client.
</p>

<p>
Since the underlying network is Ethernet, before being able to send
the TCP SYN packet the client has to perform an ARP request
to learn the MAC address for the default router. After some more messaging,
the TCP connection will be established and data transfer begins.
</p>

<p>
We'll explore these happenings in the network later, but for now just
sit back and watch the simulation. You can make the animation faster
or slower by adjusting the slider at the top of the network window.
</p>

<p class="img"><img src="images/animspeed.gif"/></p>

<p>
You can stop the simulation by clicking the red "STOP" traffic
sign icon (or by hitting F8), and resume it ("Run" icon or F5).
</p>

<p class="img"><img src="images/tb-run.gif"/></p>

<p>The "Fast" icon or (F6) will turn off message animation and
update the graphics only every 10 events or so (the exact number
can be configured in the Simulation Options dialog,
Options menu, accessible from via the toolbar as well). The "Express"
icon provides the highest speed: it turns off all GUI functions while the
simulation is running, even writing to the log is turned off.
Express mode updates the display every 1000 events or so
(also configurable in Simulation Options).
</p>

<p class="img"><img src="images/dlg-simoptions1.gif"/></p>

<p>
In Express mode you can only stop the simulation by clicking the
"Big Red STOP Button" (see below). Simulation speed in Express mode may
significantly depend on the state of the "auto update inspectors" checkbox.
</p>

<p class="img"><img src="images/dlg-stopexpress.gif"/></p>

<p>
You can read the speed of the simulation on the 3rd line of the main
window status bar. Ev/sec tells you how many events your CPU crunches
in a second -- this depends on the strength of your hardware, on the
amount processing (C++ code) to be done for an average event
(refer to the <tt>handleMessage(cMessage *)</tt> functions in the model
source), and on the run mode (Normal, Fast or Express). It is not unusual
for the Express mode to be 100-200 times faster than Fast mode.
</p>

<p class="img"><img src="images/speedbar.gif"/></p>

<p>
The other two readings on that status bar are simsec/sec (how many simulated
seconds the model progresses in one "real" second) and ev/simsec (how many events
your model contains per simulated second). The simsec/sec value is useful
for estimating how long your simulation will take. Ev/simsec is independent
of whether you use Normal, Fast or Express mode, and it only depends
on the nature and size of your model (ATM cell-level simulations will have
a few magnitudes higher ev/simsec values than call center simulations.)
</p>

<a name="restart"/><h3>Over? You can restart it!</h3>

<p>
While in Expess mode, you'll probably get the following dialog after a while:
</p>

<p class="img"><img src="images/dlg-nomoreevents.gif"/></p>

<p>
"No more events" is one way a simulation can terminate normally
(i.e. not with an error). It means that there's nothing more to
simulate -- in our simulation this occurs when the client has
successfully closed the TCP connection and finished its operation,
and there're no more packets underway and no timers running anywhere
in the whole model.
</p>

<p>
Other simulations may end with the "Simulation time limit reached -- simulation stopped"
message which means that the simulation time configured in <tt>omnetpp.ini</tt>
has been reached. (For completeness: other possibilities include
"CPU time limit reached," and "Simulation stopped with endSimulation()"
meaning that some component in the model called the <tt>endSimulation()</tt>
C++ function -- for example when it detects that desired statistical accuracy
has been reached).
</p>

<p>
In both cases you can restart the simulation using the "Rebuild network"
command on the Simulate menu. In fact, you can do that any time to start over.
</p>

<p class="img"><img src="images/m-restart.gif"/></p>

<p>
Note that some simulation models (none in INET, hopefully) may crash when
you restart the simulation. This is usually due to badly written destructor
code in the model C++ sources.
</p>

<p>
Now that we've dealt with the basics, we can go back to our ARPTest network model.
</p>

<a name="linkcolors"/><h3>OK, but what are those flashing link colors?</h3>

<p>
You've probably seen something like this:
</p>

<p class="img"><a href="images/linkcolors.gif"><img src="thumbs/linkcolors.gif"/></a></p>

<p>
If a link is yellow, that means the node is transmitting on the link.
If a node has collided and while it's backing off, the link is colored
red. Link coloring has been programmed as part of the Ethernet model
(the <tt>EtherMAC</tt> module).
</p>

<p>
The wandering red frame (around <tt>router5</tt> on the screenshot)
has nothing to do with Ethernet -- it simply indicates the location of the
current/next event in the model, as dictated by the basic
event processing algorithm of discrete event simulation.
</p>

<a name="inside"/><h3>What is inside the hosts and routers?</h3>

<p>
I bet you've found it out already, but here it is for the record: you
can double-click on a node (client, server, router) to see its internals.
</p>

<p class="img">
<a href="images/client.gif"><img src="thumbs/client.gif"/></a>
<a href="images/server.gif"><img src="thumbs/server.gif"/></a>
<a href="images/router.gif"><img src="thumbs/router.gif"/></a>
</p>

<p>
Bottom up, the client model contains:
</p>

<ul>
    <li>an Ethernet interface (<tt>eth[0]</tt>);
    <li>network layer (<tt>networkLayer</tt>, a further double-click will
        reveal it's basically IP);
    <li>a pinger application (<tt>pingApp</tt>, defunct in this model);
    <li>UDP model (<tt>udp</tt>), also not used in the ARPTest model
        (no applications configured);
    <li>TCP model (<tt>tcp</tt>). The number of connections in various
        TCP states are displayed in blue above the icon;
    <li>an application model (<tt>tcpApp[0]</tt>)
    <li>the <tt>routingTable</tt> module contains, well, the routing table
        (number of unicast+multicast routes displayed above the icon)
    <li><tt>blackboard</tt> is there for future extensions (it will be used
        in in the future as a storage place for various parameters and
        state variables different protocol layers need to share)
</ul>

<p>
A router is similar, but obviously it has nothing from L3 up. (You also see
no routing protocols -- routing is static in this model.)
</p>

<p>
If you further double-click on these components (TCP, UDP, etc.),
most of the time you'll get an <i>inspector window</i> like this.
</p>

<p class="img"><a href="images/tcpmain.gif"><img src="thumbs/tcpmain.gif"/></a></p>

<p>
It means that the component is implemented in C++, and cannot be subdivided
any further (it is a <i>simple module</i>, as opposed to <i>compund modules</i>
which are composed of submodules). The inspector window exposes the internals
of the module and we'll use it a lot later in this walkthrough, but let's just leave it
for now.
</p>

<p>
The ARPTest simulation is quite complex in that it has TCP, IP, ARP
and Ethernet in it. In this walkthrough we'll go for ARP, but the steps you learn
will be useful for exploring other protocols as well.
</p>

<a name="steps"/><h3>Steps towards exploring ARP</h3>

<p>
If we are interested in ARP, it's a bit annoying that we have to wade
throught all those Ethernet autoconfig messages until we get to the first
ARP request at 1s. Luckily, you can use the "Run until..." function to
fast-forward past them.
</p>

<p>
Restart the simulation (Simulate|Rebuild network), then click the
"Run until..." icon on the toolbar.
</p>

<p class="img"><img src="images/tb-rununtil.gif"/></p>

<p>
We know autoconfig finishes at around 1ms simulation time and first ARP
request is around 1s, so you can safely enter 2ms in the Run until dialog.
</p>

<p class="img"><img src="images/dlg-rununtil.gif"/></p>

<p>
After clicking OK, the simulation progresses past the autoconfig period in no time.
Then, both the red frame around the laptop icon (the next event marker) and the
top line of the status bar will show that the next event is going to take place
in the client PC, at t=1s simulation time. Opening "scheduled-events" in the
object tree (left side of main window) will also reveal that we have only
one event, and it is going to occur in the client application (<tt>client.tcpApp[0]</tt>).
</p>

<p class="img"><a href="images/arptest-1s.gif"><img src="thumbs/arptest-1s.gif"/></a></p>

<p>
Pressing F4 (single-step) repeatedly will take you though the next events.
You'll see as the application tells TCP to open a connection, as TCP obeys
and sends a SYN (TCP connection request) packet, as IP encapsulates SYN into
an IP datagram, and sends it down to the Ethernet interface. We could actually
peek into those messages and find out about TCP ports and IP addresses and
lots of interesting things, but let's resist the temptation and concentrate
on ARP.
</p>

<p class="img">
<a href="images/cli-activeopen.gif"><img src="thumbs/cli-activeopen.gif"/></a>
<a href="images/cli-sendsyn.gif"><img src="thumbs/cli-sendsyn.gif"/></a>
<a href="images/cli-encapsyn.gif"><img src="thumbs/cli-encapsyn.gif"/></a>
</p>

<p>
You probably noticed that the IP datagram has disappeared in the Ethernet
interface. This indicates that <tt>eth[0]</tt> is a compound module,
and if you open it (double-click), you'll find that it consists of 3
submodules (<tt>arp</tt>, <tt>encap</tt> and <tt>mac</tt>) and the IP datagram
is sitting on the input of the <tt>arp</tt> module.
</p>

<p class="img"><a href="images/ethinterface.gif"><img src="thumbs/ethinterface.gif"/></a></p>

<p>
Here we are at the beginning of the interesting part. You may actually
take a note that we are at event #94 (it's displayed in the top line of the
main window status bar) so that next time you can quickly get here
using the "Run until..." dialog (it can stop either at a simulation time or at
an event number -- or if you enter both, it'll stop at whichever comes first.)
</p>

<a name="arpbegins"/><h3>ARP begins</h3>

<p>
The <tt>arp</tt> module will tell us what's going on by writing a log. These
log messages (output via <tt>ev &lt;&lt;</tt> from the C++ code) will appear in the
main text window, but that'll soon be useless because other modules
dump their output there too. Luckily, we can open a window which
contains <tt>arp</tt>'s messages only. Right-click on the <tt>arp</tt> module, and
select "Module output" from the context menu. A new text window, titled
"(ARP)arpTest.client.eth[0].arp" will appear.
</p>

<p class="img"><a href="images/arp-ctxmenu.gif"><img src="thumbs/arp-ctxmenu.gif"/></a></p>

<p>
Then press F4 (or click the "Step" icon on the main window's toolbar)
to perform the next event and let <tt>arp</tt> process the datagram.
You'll see that:
</p>

<ul>
    <li>the datagram disappers inside <tt>arp</tt>;
    <li><tt>arp</tt> sends an ARP request
    <li>the <tt>arp</tt> text window comments what happened
</ul>

<p>
At this point your screen will look something like this.
</p>

<p class="img"><a href="images/arp-req-sent.gif"><img src="thumbs/arp-req-sent.gif"/></a></p>

<p>
ARP maps L3 addresses (IP address) to L2 addresses (Ethernet MAC address).
It uses a lookup table (ARP cache) for this purpose, but if an IP address
is not found in the table, ARP has to ask around by sending a broadcast
ARP Request. That's what we have seen here. Let's check it in detail!
</p>

<a name="requestpacket"/><h3>The ARP Request packet</h3>

<p>
Double-click on the ARP request packet to open its inspector window,
then click the "Fields" tab.
</p>

<p class="img"><a href="images/arpreq-fields.gif"><img src="thumbs/arpreq-fields.gif"/></a></p>

<p>
The "Fields" page shows the contents of the ARP packet: source MAC address,
destination MAC address, source IP address, destination IP address.
The source MAC and IP addresses are our own addresses (in the model,
autoconfigured MAC addresses begin with "0A AA"); the destination IP
address contains the address to be resolved, and the destination MAC
address is empty because that's what we're requesting.
</p>

<p>
The ARP packet is a single C++ object, with its class <tt>ARPPacket</tt>
having an <tt>int _opcode</tt> data member, <tt>int opcode()</tt> and
<tt>setOpcode(int)</tt> functions, and similar data and functions for the
other data fields as well. However, the class was not hand-coded but
generated from a <tt>.msg</tt> file, which has a very concise format:
</p>

<pre class="src">
<i>// file: ARPPacket.msg</i>
message ARPPacket
{
    fields:
        int opcode enum(ARPOpcode);
        MACAddress srcMACAddress;
        MACAddress destMACAddress;
        IPAddress srcIPAddress;
        IPAddress destIPAddress;
};
</pre>

<p>
Definition via a <tt>.msg</tt> file not only saved a lot of programming effort,
but it was also necessary for the packet's content to be displayed in the
"Fields" page.
</p>

<p>
So far so good, but how do lower layers (Ethernet) know which MAC address
the ARP request should be sent to? That's not part of the packet!
</p>

<p>
This information is attached to the packet in small data structure called
"control info". Control info is also a C++ object and similarly to packets,
its C++ source is generated from <tt>.msg</tt> files.
You can view the contents of the control info attached to this ARP packet
by clicking the "Control info" tab in the window.
</p>

<pre class="src">
<i>// file: EtherCtrl.msg</i>
class EtherCtrl
{
    fields:
        MACAddress src;  // used with ETHCTRL_DATA
        MACAddress dest; // used with ETHCTRL_DATA
        int etherType;   // used with ETHCTRL_DATA and EthernetIIFrame
        int ssap;        // used with ETHCTRL_DATA and EtherFrameWithLLC
        int dsap;        // used with ETHCTRL_DATA/REGISTER_DSAP/DEREGISTER_DSAP
        int pauseUnits;  // used with ETHCTRL_PAUSE
};
</pre>

<p class="img"><a href="images/arpreq-ctrlinfo.gif"><img src="thumbs/arpreq-ctrlinfo.gif"/></a></p>

<p>
It says that source MAC address is not specified (all zero -- in this case
it'll be filled in by Ethernet) and the destination MAC address is all FF's
(the Ethernet broadcast address). SSAP and DSAP are unused here (they're for
802.3 frame type but we use Ethernet II frames in this simulation), and pauseUnits
has also no significance (only used for telling MAC to send PAUSE frames).
etherType is set to zero here. <!-- FIXME set etherType to proper value -->
</p>

<a name="pendingqueue"/><h3>The pending queue</h3>

<p>
While ARP resolution is pending, IP datagrams which wait for it have to be
buffered somewhere. There's a <tt>"q=1"</tt> label next to the <tt>arp</tt>
icon -- if you double-click on it (on the <tt>"q=1"</tt> text, not on the icon!),
an inspector window will open displaying the queue of buffered datagrams.
</p>

<p class="img">
<img src="images/arp-icon.gif"/>
<a href="images/arp-queue.gif"><img src="thumbs/arp-queue.gif"/></a>
</p>

<p>
You may double-click on the SYN line again, to view the datagram's contents
(source and destination IP address, TTL, encapsulated protocol, etc.)
in an inspector window, much the same way as it worked with the ARP request
packet. One "extra" is worth mentioning, however: on the "General" page
you'll find the "Encapsulated message" button which will take you to the
TCP packet in the datagram -- and you can continue exploring the
TCP header fields.
</p>

<p class="img"><a href="images/ipdgram.gif"><img src="thumbs/ipdgram.gif"/></a></p>

<a name="arpcache"/><h3>The ARP cache</h3>

<p>
You've noticed the blue letters "1 cache entries, send req:1 repl:0 fail:0"
above the <tt>arp</tt> icon, and wondering what the ARP cache contains right now.
No problem, we can check it out!
</p>

<p>
Double-click the <tt>arp</tt> icon (or right-click on it and select "As object..."
from the context menu). An inspector window will open, with several pages like the
message inspector -- you'll need the "Contents" page now.
</p>

<p class="img">
<a href="images/arp-ctx-asobj.gif"><img src="thumbs/arp-ctx-asobj.gif"/></a>
<a href="images/arp-contents.gif"><img src="thumbs/arp-contents.gif"/></a>
</p>

<p>
The list reveals that we have several counters here for sent and received ARP requests
etc, a queue for IP datagrams pending ARP resolution -- and also the ARP cache.
Double-click on the <tt>arpCache</tt> line. Another inspector will open, this time
the following one:
</p>

<p class="img">
<a href="images/arpcache1.gif"><img src="thumbs/arpcache1.gif"/></a>
<a href="images/arpcache2.gif"><img src="thumbs/arpcache2.gif"/></a>
</p>

<p>
First of all, you'll notice that the cache contains what you'd probably expect:
one entry, IP address 10.0.0.1, pending resolution. (The "Detailed info" line
on the first page would show only the first three entries, hence the second page
-- it is also easier to browse if there're many entries in the cache.)
</p>

<p>
Second, if you're familiar with C++, you'll notice that the ARP cache is
implemented with a standard STL <tt>map</tt>. The <i>key</i> in the map
is <tt>class IPAddress</tt> and the <i>value</i> is
<tt>struct ARPCacheEntry</tt> (or rather, a pointer to it). If you'd be
looking in the C++ code to find out what makes STL map able appear like
this in the GUI, you'd find only one extra statement:
<tt>WATCH_PTRMAP(arpCache)</tt>, plus <tt>&lt;&lt;</tt> operators
defined for <tt>IPAddress</tt> and <tt>ARPCacheEntry</tt>. That's all
it takes -- the rest is up to the simulation environment.
</p>

<p>
But let us follow the ARP request further.
</p>

<a name="transmission"/><h3>Transmission over Ethernet</h3>

<p>
With a further F4 key (or "Step" toolbar button), <tt>encap</tt>
will encapsulate the ARP request into an Ethernet II frame.
You can verify by double-clicking
on the message and opening an inspector that the destination address
in the frame has been set to broadcast (all FF's). The source address
is still all zeros, it'll be set by MAC. On the "General" page you
can verify that the ARP packet has been indeed encapsulated in an
Ethernet frame. (You can close all other inspector windows now,
except the <tt>arp</tt> text window.)
</p>

<p>
The next F4 key, the frame gets into <tt>mac</tt>'s buffer. (Note that
"q=0" has changed into "q=1" -- if you double-click on the text,
you'll actually see the queue where the frame is buffered.) But why is it
not transmitted immediately? If you peek into the log in the main
window, the solution is there: it says <tt>"wait IFG first"</tt>. IFG stands for
Inter-Frame Gap in the Ethernet standards, and it is the time needed
by older Ethernet hardware to switch from receive (carrier sense)
mode to transmit mode. In the model, end of the IFG is marked with
an event which can also be seen in "scheduled-events".
</p>

<p class="img"><a href="images/wait-ifg.gif"><img src="thumbs/wait-ifg.gif"/></a></p>

<p>
Hitting F4 again makes <tt>mac</tt> process the EndIFG event, and
start transmitting the frame. The icon and also the connection arrow
turns yellow, indicating that a transmission is going on.
</p>

<p class="img">
<img src="images/mac-tx.gif">
<img src="images/arptest-startrx.gif">
</p>

<p>
Most actions we've seen so far, from <tt>app</tt>'s TCP Active OPEN
command to encapsulation of the ARP packet into an Ethernet frame,
took zero simulation time. We assumed that -- compared
to other time periods occurring in the model -- they take such a short
time that it is not worth modelling explicitly (they wouldn't make
a difference in the simulation results).
</p>

<p>
However, the time an Ethernet frame transmission takes <i>is</i>
interesting to us, and so is propagation delay on the cable (the cable may be
long) -- so in fact we have four discrete points of time, and we need
four simulation events to model them:
</p>

<ul>
    <li>transmitter starts transmitting the frame
    <li>beginning of frame reaches receiver (start receiving)
    <li>transmitter completes transmission
    <li>end of frame reaches receiver (end of reception)
</ul>

<p>
The message which you've seen <tt>mac</tt> having sent (the Ethernet
frame message object in fact) represents the <i>beginning</i> of the frame.
End of transmission is an event you'll find in "scheduled-events", it is
a self-message scheduled by the transmitting <tt>mac</tt>:
</p>

<p class="img"><img src="images/endtx-event.gif"></p>

<p>
The "start of reception" event will occur in the receiver of course,
and will be represented by the arrival of the Ethernet frame message
object. You can see in the first line of the status bar, in the
"next event" field that it's going to be the next event, and will take
place in <tt>router1</tt>'s second interface (<tt>eth[1]</tt>).
</p>

<p class="img"><img src="images/statusbar-startrx.gif"></p>

<p>
Open the graphics for this Ethernet interface by double-clicking
on <tt>router1</tt>, then on <tt>eth[1]</tt> (just follow the red frames
which indicate the location of the next event).
</p>

<p>
Pressing F4 once more makes this <tt>mac</tt> process the event and
go into "receiving" state -- its icon will also turn blueish to indicate
it. From the frame length and the data rate <tt>mac</tt> has calculated
the time the last bit will arrive (end reception), and scheduled an
event accordingly (you can verify it in the "scheduled-events" list).
</p>

<p class="img">
<a href="images/router1-rx.gif"><img src="thumbs/router1-rx.gif"/></a>
<a href="images/router1eth1-rx.gif"><img src="thumbs/router1eth1-rx.gif"/></a>
</p>

<p>
During the next few F4 keypresses, the client laptop <tt>mac</tt> will
finish transmission, the <tt>router1</tt>'s <tt>mac</tt> will complete
reception, and it will pass up the frame to <tt>encap</tt> which in turn will
rip the Ethernet header and pass up the ARP Request packet to <tt>arp</tt>.
</p>

<a name="arpreply"/><h3>ARP Reply</h3>

<p>
In the next event, <tt>arp</tt> will process the request. Hit F4.
If you had <tt>arp</tt>'s module output window open, it'll show what happened.
</p>

<p class="img"><a href="images/arp-reply-sent.gif"><img src="thumbs/arp-reply-sent.gif"/></a></p>

<p>
ARP took the source IP address and source MAC address, and added them
to its own ARP cache. Then it had to determine whether to reply to the
request. The destination IP address was did not belong to the router;
however, proxy ARP is turned on (you can verify this in the ARP module's
inspector window, "Params" page -- see below). With proxy ARP, the
router has to reply to the ARP Request if it can route the address, and
send back its own MAC address. That's what happened here.</p>

<p class="img"><a href="images/arp-params.gif"><img src="thumbs/arp-params.gif"/></a></p>

<p>
While ARP processed the request packet, you probably saw a red flashing
arrow, like this:
</p>

<p class="img"><a href="images/arp-outputport.gif"><img src="thumbs/arp-outputport.gif"/></a></p>

<p>
It indicates ARP asking the routing table component whether the address
10.0.0.1 is routable, as part of the proxy ARP process. (More precisely,
ARP asks which is the output port for that address -- if the reply is "none"
it means the address is not routable). In the C++ code, what you've seen
was the animation of a direct method call -- ARP module's C++ code
invoked the <tt>int outportNo(IPAddress)</tt> method of the routing table
object (class <tt>RoutingTable</tt>) with 10.0.0.1 as argument.
It was the simulation environment which made this request visible
in the simulation GUI.
</p>

<p>
The answer was probably "routable", because <tt>arp</tt> sent a reply.
You can verify by opening the ARP Reply packet: source and destination
fields have been swapped, and the now-source (formerly destination)
MAC address field contains the MAC address of this interface.
</p>

<p class="img"><a href="images/arpreply-fields.gif"><img src="thumbs/arpreply-fields.gif"/></a></p>

<p>
The next few F4 keypresses will transmit the ARP Reply over Ethernet
back to the client's ARP.
</p>

<a name="procreply"/><h3>Processing the ARP Reply</h3>

<p>
Results of processing the ARP reply can be seen in the next screenshot.
The MAC address of the router's Ethernet interface has been added to the
ARP cache. ("age=0" in the cache entry is needed because after certain
period of inactivity [120s configured here] the entry is considered
obsolete and gets thrown out of the cache. In fact, the entry really stores
last update time, but age is more practical when displayed.)
The datagram carrying the TCP SYN segment that was wainting in the queue
has been sent down to Ethernet for transmission.
</p>

<p class="img"><a href="images/arp-resolved.gif"><img src="thumbs/arp-resolved.gif"/></a></p>

<p>
You can even verify that the control info attached to the datagram
indeed contains the MAC address just received via ARP.
</p>

<p class="img"><a href="images/syn-ctrlinfo.gif"><img src="thumbs/syn-ctrlinfo.gif"/></a></p>

<a name="syn"/><h3>The client's SYN gets to the server</h3>

<p>
Now that ARP has done its job, you can hit F5 (or click "Run" on the main
window toolbar), sit back and watch as the SYN packet makes its way to the
server. It is still not any easy job for SYN, because this example
network is full of distinct Ethernet segments, so it'll take still
a series of ARP requests and replies get to the server.
</p>

<p>
You'd maybe think that the remote TCP's response, SYN+ACK will have easier
job on the way back, because SYN paved the way for it. But not really:
it was the IP addresses of routers initiating ARP resolutions that
made it into the ARP caches, and not the client's IP address 10.0.0.10.
So the series of ARP request/replies repeats as SYN+ACK progresses
back to the client computer.
</p>

<p>
But further packets really don't have to go through ARP resolution
any more. If you kept the client's <tt>arp</tt> output window open,
you can see it fill with reports about cache hits:
</p>

<p class="img"><a href="images/arp-log.gif"><img src="thumbs/arp-log.gif"/></a></p>

<a name="discovering"/><h3>Following ARP from the documentation</h3>

<p>
In the above guided tour, you've seen how to run a simulation model,
view logs, examine packet contents, look at queues, and explore internal
tables and variables. But what do you do if something is still not
clear? If log messages do not give enough information to find out how
the thing works?
</p>

<p>
The answer is: <i>documentation</i>. The INET framework's documentation
essentially contains the <i>full source code (!!!)</i> -- in an organized,
readable, searchable and cross-referenced manner.
If you have the INET Framework demo, then you probably have the full
documentation as well, in the <tt>Documentation/</tt> folder. You can
open it from the demo application too:
</p>

<p class="img"><a href="images/rundemo-doc.gif"><img src="thumbs/rundemo-doc.gif"/></a></p>

<p>
When you open it, you should see in your browser something like the picture
below. I marked the possible starting points for exploring ARP. Basically,
if you know what you're looking for (we know now), just click <tt>ARP</tt>
on the "All modules" list on the left (or click "modules, simple" link
on the top of that frame, and choose from the shorter list). If you don't
know, you can start from an example network (here: <tt>ARPTest</tt>),
and click on submodules until you find what you're looking for.
</p>

<p class="img"><a href="images/doc-frontpage.gif"><img src="thumbs/doc-frontpage.gif"/></a></p>

<p>
ARP's page itself doesn't tell us too much about the ARP protocol or this
particular implementation (this may improve in the future),
but it does tell that it's employed as part of <tt>EthernetInterface</tt>
(and by following that link you can learn where, in turn,
<tt>EthernetInterface</tt> is used, etc.) and also lists the parameters
and gates (or ports) (further below, not shown in the screenshot).
It also contains its NED definition (also further below), and what's important
for us now, there's a link to the C++ documentation.
</p>

<p class="img"><a href="images/doc-arp.gif"><img src="thumbs/doc-arp.gif"/></a></p>

<p>
Click the "C++ documentation" link. The C++ documentation that emerges
has been generated from commented C++ source by the Doxygen tool, with its
<tt>INLINE_SOURCES</tt> option turned on. The sheer size and detail of the
C++ documentation might be overwhelming to you, but not if you know
where to start looking.
</p>

<p>
There are two good starting points: the <tt>handleMessage(cMessage*)</tt> member
function, and the data structure used in the module (Doxygen lists data members
under the <i>Protected</i> (or <i>Public</i> or <i>Private</i>) <i>Attributes</i>
heading). <tt>handleMessage(cMessage*)</tt> is the function that gets invoked
whenever a message (packet, etc) arrives at the module or a timer goes off
(a message scheduled by the module itself comes back).
</p>

<p class="img"><a href="images/doxy-arpclass.gif"><img src="thumbs/doxy-arpclass.gif"/></a></p>

<p>
As a rule of thumb: whatever large number of functions you see in the
documentation, always click at <tt>handleMessage()</tt> first. If the
module code was well written, it'll lead you from there. Let's do that with
<tt>ARP</tt> as well.
</p>

<p class="img"><a href="images/doxy-handlemsg.gif"><img src="thumbs/doxy-handlemsg.gif"/></a></p>

<p>
Function names are displayed in blue -- clicking one will take you to the
code of that function. Combined with the browser's "Back" button, they offer
a very convenient way to explore the source.
</p>

<p>
Here's what <tt>handleMessage()</tt> says: if the message that arrived is a
self-message (expired timer), it can only be that an ARP request has timed
out, and we'll handle it. Otherwise the message can only be a packet which
we got either from the higher layers (IP) or from the network.
</p>

<p>
If it came from the network (arrived on our gate named <tt>"hwIn"</tt>),
then we must differentiate if it's an ARP packet or something else
(for example, IP datagram). This is done by trying to <tt>dynamic_cast&lt;&gt;</tt>
the message to <tt>ARPPacket</tt> -- if the result is not <tt>NULL</tt>,
it is an ARP packet and we process it accordingly. Otherwise we just process
it as some other inbound packet (and we'll just pass it up).
</p>

<p>
If didn't come it came from the network, then it must be an outbound
packet, and we process it as such.
</p>

<p>
Finally, we update the <i>display string</i> -- a property which controls
how the module is presented on the GUI. Hence the <tt>if (ev.isGUI())</tt>
statement in the code: we don't care about that if the simulation is running under
a command-line user interface (that is, if the simulation program was
linked with Cmdenv instead of Tkenv -- search for these two words in the
OMNeT++/OMNEST documentation if you're interested.)
</p>

<p>
The display string can also be viewed (and changed) in the GUI: it is on
the "Info" page of the module's inspector window (the one that opens
by double-clicking the icon or selecting "As object" from its context menu):
</p>

<p class="img"><a href="images/arp-dispstr.gif"><img src="thumbs/arp-dispstr.gif"/></a></p>

<p>
It consist of "tags" separated by semicolons. For example, <tt>"i=..."</tt>
specifies the icon to display, <tt>"p=..."</tt> specifies position, and
<tt>"t=..."</tt> specifies the text which appears (by default) in blue
above the icon. (You can try: change the string on the GUI, press Enter
or click the green checkmark, and see.) After this introduction, the
meaning of the <tt>updateDisplayString()</tt> function is obvious:
it <tt>sprintf</tt>'s together a suitable string, and sets it as value
of the <tt>"t"</tt> tag, making it appear above the icon. The text will
contain the number of entries in the <tt>arpCache</tt> variable (an STL map),
and the values of the <tt>numRequestsSent</tt>, <tt>numRepliesSent</tt> and
<tt>numFailedResolutions</tt> variables.
</p>

<p class="img"><a href="images/doxy-updatedispstr.gif"><img src="thumbs/doxy-updatedispstr.gif"/></a></p>

<p>
After this detour about display strings, let us return to ARP message
processing. Processing non-ARP packets coming from the network
will not cause you much surprise: they are just passed up to the higher
layer (sent via the <tt>"hlOut"</tt> gate) after stripping the Ethernet's
control info (which tells e.g. the source MAC address -- higher layers
won't need it). As we already mentioned, the <tt>ev&lt;&lt;</tt> line
writes to the main window and the module's output (log) window if it's open.
</p>

<p class="img"><a href="images/doxy-processinbound.gif"><img src="thumbs/doxy-processinbound.gif"/></a></p>

<p>
Processing an ARP packet (<tt>processARPPacket()</tt>) begins with
a long comment quoting the message processing logic from RFC 826,
and code below that follows the recipe almost word-by-word -- you'll
surely manage to make sense of it.
</p>

<p class="img"><a href="images/doxy-processarp.gif"><img src="thumbs/doxy-processarp.gif"/></a></p>

<p>
Instead, let us have a look at the processing of packets coming from higher
layers, that is, IP datagrams. If the MAC address for the destination IP address
is in the cache, we just attach it to the packet in an Ethernet control info
(<tt>EtherCtrl</tt> class), otherwise we have to start the ARP resolution process.
Here're the crucial parts of the code (the full code has a bit longer if-ladder,
because timed out cache entries and already pending resolution processes also
have to be accounted for):
</p>

<p class="img"><a href="images/doxy-processoutbound.gif"><img src="thumbs/doxy-processoutbound.gif"/></a></p>

<p>
... extract next hop IP address, or if not present the destination IP address
into the <tt>nextHop</tt> variable ...
</p>

<p class="img"><a href="images/doxy-processoutbound1.gif"><img src="thumbs/doxy-processoutbound1.gif"/></a></p>

<p>
... The code above added to the cache a new entry (which maps <tt>nextHopAddr</tt>
to the newly added entry, with a blank MAC address and marked as pending),
sent an ARP Request, and queued up the datagram. Next come some more
<i>else if ()</i> clauses to check cache entry is not stale and not pending
resolution, then ....
</p>

<p class="img"><a href="images/doxy-processoutbound2.gif"><img src="thumbs/doxy-processoutbound2.gif"/></a></p>

<p>
If you have some experience in using STL classes, reading the code should
not be too difficult -- otherwise you may want to browse the web for STL tutorials
or borrow a decent C++ book. (Or borrow a friend who explains it in a few words :))
</p>

<p>
In the above code, after we successfully extracted the MAC address out of the cache,
sending of the IP datagram was done via the <tt>sendPacketToMAC()</tt> function.
This function has been copied below -- it just creates a control info object,
puts the MAC address into it, attaches the object to the packet and sends it
on gate <tt>"hwOut"</tt> which is connected to Ethernet's <tt>encap</tt> and
<tt>mac</tt> modules.
</p>

<p class="img"><a href="images/doxy-sendtomac.gif"><img src="thumbs/doxy-sendtomac.gif"/></a></p>

<p>
Finally, as the last thing in this tutorial, we can have a look at the
<tt>sendARPRequest()</tt> function which is the meat of the (otherwise very short)
<tt>initiateARPResolution()</tt> function. It shows how to create
an ARP packet, fill its fields and send it. (Sending actually uses the
<tt>sendPacketToMAC()</tt> function from above.)
</p>

<p class="img"><a href="images/doxy-sendarpreq.gif"><img src="thumbs/doxy-sendarpreq.gif"/></a></p>

<a name="conclusion"/><h3>Conclusion</h3>

<p>
While ARP might not be the most important protocol on earth, it was chosen as the
topic of this tutorial because it is simple enough to be presented in such
a short space, and yet it does something interesting -- with the results
immediately visible. And not least, it is well known and on everybody's desk
(who doesn't have Ethernet LAN?).
</p>

<p>
It is not ARP which is important anyway. By following the tutorial, you've
acquired significant knowledge which will be applicable whichever part
of INET (or another OMNET++/OMNEST simulation model) you're going to explore.
You've learned how to run a model, how to explore it by looking at
module output, by peeking into packets, queues and internal tables, and
how to browse the documentation and read the source code for answers.
</p>

<p>
I hope you've found this tutorial useful. If you have questions, comments
or suggestions to improve it, please write to <u>andras at omnetpp org</u>.
</p>

<br><br>

</body>
</html>