Project 3 - The ping program
Introduction
This project is an extension of project 2 where a stub was
provided for the Logical Link Control, LLC. In addition, the ARP,
IP, and ICMP, protocols will be used in this project in order to
implement the response to a ping request. This project is
completed when the ping program receives the correct response to
an ARP request, and ICMP echo replies in response to echo
requests.
There is some administration in order to obtain the source code. Refer to the suggested design of the class
hierarchy as well as advice on how to approach the completion of the skeleton code. An
executable which may be loaded into the ETRAX unit is compiled, linked, and loaded in the
same manner as in the previous overview of the system. Finally,
you will have to test your solution.
Recommended reading
Read chapter 3, the internet protocol (IP), and 4, the address
resolution protocol (ARP), as well as chapters 6 and 7, about
ICMP and the ping program in [Stevens96]. Chapters 9, IP routing,
and 10, dynamic routing protocols, are recommended reading as
well although they are not essential for the implementation in
this project. An ethernet frame description is presented in p.23.
Consult RFC826
on ARP, RFC791
on IP, and RFC792
on ICMP.
The ping program
The ping program is often used as a tool in order to find a
diagnose to network problems. It tests whether another host is
reachable by sending an ICMP echo request. First of all though,
the program must
- find the IP address, and,
- find the ethernet address of the other host,
in order to send the echo request to the right destination.
The host name of the server implementation will be used
instead of the IP address, e.g. the server godzilla
has the IP address 192.168.10.60 and the ethernet address
02:67:01:04:02:37. When the command ping
godzilla is executed on the host linus
the address resolving depends on several steps.
- A search for the host godzilla
in the file /etc/hosts is
performed. If the IP address 192.168.10.60 is defined for
godzilla in the file, it
is deduced that it is the same subnet which linus belongs to and it is
possible to reach godzilla
without a router inbetween.
- The next step is to associate an ethernet address with
the IP address found. An ARP, address resolution
protocol, request is sent as a broadcast to all hosts on
the network. The question asked in the request is: who
has the IP address 192.168.10.60? Since the request is
sent as a broadcast, every host on the network will
decode the ARP packet and compare the IP address received
with the one defined for the host.
- If the host godzilla is
online, it will identify the ARP request as directed to
it and send an ARP reply back. The reply will contain the
ethernet address and the IP address, and inform the
requesting host: I am 192.168.10.60 and my ethernet
address is 02:67:01:04:02:37.
- When the ARP reply is received by linus
it is possible to assemble the first ICMP echo
request and send it to the IP address of godzilla
with the right ethernet address associated.
- The host godzilla receives
the request and decodes
it in the different layers ETHERNET, LLC, IP and ICMP, in
order to deduce that it is an ICMP echo request directed
to godzilla.
- Finally, the host godzilla
assembles an ICMP echo reply and sends it to the host
where the request originated. It is then the
responsibility of the program ping to present the
information on the screen in a sensible way.
An important observation is that the host godzilla
does not know its name, just its IP and ethernet address. The
association between the name and the IP address is performed
locally by linus.
Suggested solution design
The figure shows the information flow both for a packet
received and a packet transmitted. In the previous project, the
class EthernetInPacket was
implemented. The stub provided for the Logical Link Control, LLC,
handled ICMP packets in a crude way and will be replaced in this
project. In addition, ARP, IP, and ICMP will be partially
implemented. The TCP part will be considered in the next project.
The class diagram below describes the design of the solution
for the four protocols to be implemented in this project. Each
class is defined in the header files llc.hh,
arp.hh, ip.hh
and icmp.hh, which are provided
for guidance. The corresponding *.cc
files are not provided and will contain the code implemented when
the project is finished.
A container for the IP address is provided as the class IPAddress in the files ipaddr.[hh,cc].
These files also define and implement a function which calculates
checksums, calculateChecksum.
Details in the
implementation
Big and little endian revisited
Remember, all protocols in TCP/IP are big endian whereas the
ETRAX architecture is little endian. Thus, the opposite ordering
of bytes in integers are used. The macro HILO solves the
translation between the two endian formats. For example,
uword realPacketLength =
HILO(anIPHeader->totalLength);
anIPHeader->totalLength =
HILO(realPacketLength);
Only 16 bit integers are affected since integers only are
interpreted in the sense of big or little endian. Other fields,
e.g. the IP address and the ethernet address, are interpreted
without being affected by the endian.
No rule without an exception. The function calculateChecksum
returns a result which is big endian, according to the network
byte order, and should not be altered.
anIPHeader->headerChecksum =
calculateChecksum((byte*)anIPHeader,
IP::ipHeaderLength,
0);
Memory leaks
A check of memory leaks (dynamically allocated memory not
returned to the system) may be accomplished by a printout in the
frontpanel class for example. Every time a LED blinks the total
amount of memory left in the system may be printed with the
statement
cout << "Core "
<< ax_coreleft_total() << endl;
The LLC layer
- It may be assumed that ethernet encapsulation (RFC894)
only should be detected. The IEEE 802.2/802.3
encapsulation (RFC1042) may be ignored [Stevens96] p.23.
It is advisable however that the IEEE 802.2/802.3 frame
is decoded. The ambitious student should implement this!
- The type field in the ethernet frame is used in order to
distinguish between ARP packets and IP datagrams
[Stevens96] p.23.
- Detect ARP packets and IP datagrams and send them to the
appropriate layers for further processing.
The ARP layer
- Detect an ARP requst where the target IP address is that
of your server [Stevens96] sec.4.4, and generate an ARP
reply packet containing the ethernet address of your
server in response.
The IP layer
- The different fields in the IP datagram are described in
[Stevens96] sec.3.2.
- It may be assumed that the issues of routing as well as
fragmented IP datagrams can be ignored.
- The only packets to be processed are those addressed
directly to the server, all IP broadcasts may be ignored.
- Detect ICMP echo requests and send them to the approriate
layer. Local copies of fields are only needed for the protocol field which describes
what type of IP datagram it is, TCP, ICMP, UDP,
..., and the source IP address,
which defines the host sending the request. Both fields
are used in generating an ICMP echo reply.
There are a number of issues to consider in the process
of decoding an IP datagram.
- Check the version field
and make sure it contains the value 4.
- Check the header length
field. Process the packet if the field contains the value
5. Either throw the packet away or calculate the start of
the data content if the value is larger than 5.
- Ignore the type of service
field at present.
- Use the field total length
in order to calculate the length of the packet to be sent
on to the upper layers of the stack. This is important as
the packet may contain frame padding from the ethernet
layer.
- Ignore the identification
field since fragmentation will not be handled at present.
- Make sure the packet is not fragmented by a check that
the field fragmentFlagsNOffset (defined in the class
IPHeader) & 0x3FFF is zero.
- Ignore the time to live
field since routing is ignored at present.
- Extract and save the content of the field protocol.
It is needed for replies.
- Ignore the checksum field
as the checksum of the ethernet frame has already been
determined as correct in a lower layer.
- Extract and save the content of the field source
IP address. It is needed for replies.
- Check if the field destination IP
address contains the address of your server.
The packet may be thrown away if the IP address is
different from that of your server. This field is the
first to check if an effective algorithm is desired.
The assembly of a reply packet is accomplished as follows.
- Set the version field to
4.
- Set the header length
field to 5.
- Set the type of service
field to 0.
- Calculate and set the total length
field.
- Set the identification
field to a unique sequential number, e.g. the value of a
global variable which is incremented each time an IP
packet is sent.
- Set the field fragmentFlagsNOffset to 0.
- Set the time to live field
to 64, which is the default in TCP/IP.
- Set the field protocol to
the value saved in the decoding process.
- Set the checksum field to
0 in to prepare for the checksum calculation.
- Set the field source IP address
to the IP address of your server.
- Set the field destination IP address
to the source IP address saved in the decoding process.
- Calculate the checksum of the IP header with the provided
function calculateChecksum and store the value in the
field checksum.
ICMP
- Detect ICMP echo requests and answer them [Stevens96]
p.86. The assembly of a reply packet is accomplished by
changing the fields type
and checksum.
Source code, compilation,
linking and loading
Make sure your present working directory is ~/kurs/src.
Remove the subfolder lab3 if it
exists in ~/kurs/src. Then, copy
all files from your solution in project 2 with the command
cp -r lab2 lab3
and change your present working directory into ~/kurs/src/lab3.
This project will be an extension of your solution in project 2.
Add the skeleton of project 3 to your previous files with the
command
cp -r ~inin/kurs/src/lab3/* .
There should be six files in addition to the ones from project
2 in the directory lab3,
- llc.hh, a declaration of
the class LLCInPacket,
- arp.hh, declarations of
the classes ARPInPacket and ARPHeader,
- ip.hh, declarations of the
classes IP, IPInPacket and IPHeader,
- icmp.hh, declarations of
the classes ICMPInPacket, ICMPHeader and ICMPECHOHeader,
- ipaddr.hh, declarations of
the class IPAddress and the function calculateChecksum,
and
- ipaddr.cc, the
implementation of the declarations in the corresponding
header file.
The file llc.cc from project 2
will need modifications in order to replace the stub with
functional code. In addition, arp.cc,
ip.cc and icmp.cc
must be created from scratch.
The target of the make process is defined in the file /kurs/make/lab3/modules. Make sure that
your present working directory is ~/kurs/make
and type the commands:
- genmake -no-lint-files lab3,
which creates a new makefile for the new target source
code,
- axmake -clean lab3, which
removes all old object files created in previous
compilations (very important as the make application
could use outdated object files),
- axmake lab3, which
compiles and links the new target source code.
Testing the solution
The tools in this project are
- the program ping which is to be executed on the server linus, or one of the NT machines
and,
- the network monitor executing on the NT-workstation.
The ping program is used in order to test the solution.
- log on linus,
- execute the command arp -d your-IP-address,
in order to remove a possible entry in the ARP cache,
- check the ARP cache with the command
arp -a in order to make sure its clean,
- execute ping your-IP-address
(terminate the command with Ctrl-C), and,
- check if the ARP cache contains an association between IP
number and ethernet address with the command
arp -a your-IP-address.
The ping-program has an option -s
which sets the packet size to be transmitted. Try sending packets
with various sizes from 4 to 1450 and make sure you understand
which packet sizes are critical,
Test the behaviour of the ping program by executing the
command ping print-1. It will show
the response of a working IP stack if you are uncertain on what
to expect. When everything is working in your server solution,
the response in the terminal window will look the same.
Use the application Ethereal
in order to detect what is sent on the network
Note that the ARP packets must be processed
correctly in order to allow the ping program to send ICMP
requests. Even if the ARP processing is working, the ICMP
processing might be incorrect.