1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027 |
- <!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 <<</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 <<</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><<</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<></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<<</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>
|