ARP Lab
Background:
The Address Resolution Protocol is used to determine the Ethernet
address of a host given the IP address. For our experiments, the
ARP code is a separate object that sits between the Ethernet layer and
the internet layer. The push method on the ARP object will be
passed the IP address of the desired destination. The ARP code
should then look up that IP address in the ARP table to see if there is
a corresponding Ethernet address. If so, that Ethernet address
will be used to push the same payload to the Ethernet layer. If
the IP address is not found, then the ARP object will create an ARP
packet, send it out on the broadcast Ethernet address and wait for a
reply. The host with the corresponding IP address should reply
with an ARP packet. If there is no response within 10 seconds,
then the ARP push routine should print an error message and return.
The ARP packet is contained directly in an Ethernet packet and does
not have an IP header. In order to recognize the ARP packet, you
need to look at the type field in the Ethernet packet. The type
field should be 0x806 for ARP packets. Because Ethernet assigns a
single type value to ARP, an Ethernet frame that contains an ARP request
message will have the same type as an Ethernet frame that carries and
ARP response. The receiver must examine the OPERATION field in the
ARP packet to determine whether an incoming message is a request or a
response.
This list of current Ethernet types
may be interesting to you. The most important numbers are:
- 0-0x5dc are reserved for IEEE802.3 Length Field. If the
type is in this range, it is interpreted as a 802.3 packet with the
length in the type field. Since Ethernet packets are limited to
1500 bytes, the reserved values can identify any valid length for a
packet.
- 0x806 is the ARP type.
We will provide you with physical and ethernet layers that will allow
you to talk directly to the real ethernet in the lab. The ethernet
layer will interpret the length parameter as both length and ethernet
type. The top 16 bits of the length field will have the type field
for the ethernet packet. The bottom 16 bits will have the actual
length to be pushed. The same interpretation will be made for
packets that are being "popped" up from the ethernet layer to your arp
code. Be careful here, because if you don't strip off the top 16
bits, it will look like a really long pop (you should "and" the length
parameter with 0xffff in order to get the real length). You should also
use caution in interpreting the meaning of the length parameter. It is
the length of the ethernet frame, not the length of the protocol packet
inside of the frame. You will need to look at the header of the protocol
(ARP or IP) in order to determine the amount of data in the packet.
When sending an ARP packet, the destination address should be the
broadcast Ethernet address (0xff ff ff ff ff ff). The ARP layer
should use this address when sending an ARP packet. When the
Ethernet layer sees this address, it will pass the packet up the stack,
even though it does not match the hardware Ethernet address.
Specifications:
You should study the material on pages 258-261 in order to
complete this lab successfully. The format for an ARP packet is
described on page 260.
Here is an example of how an ARP packet should look - http://students.cs.byu.edu/~cs460ta/cs460/labs/arpfigure.html.
| Hardware type = 1 |
ProtocolType = 0x800 |
| HLen=6 |
PLen=4 |
Operation |
| SourceHardwareAddr (bytes 0-3) |
| SourceHardwareAddr(bytes 4-5) |
SourceProtocolAddr(bytes 0-1) |
| SourceProtocolAddr(bytes 2-3) |
TargetHardwareAddr (bytes 0-1) |
| TargetHardwareAddr (bytes 2-5) |
| TargetProtocolAddr (bytes 0-3) |
The ARP layer object will be very similar to the physical layer object
you wrote in a prior lab. The ARP layer object must support the
following methods:
- init ( char *name,
protocol *higher, protocol *lower, char *addr, int port,
int client); The initialization code will be called with the addr
field corresponding to your machine's IP address in the bottom 32 bits
and your machine's ethernet address in the top 48 bits (for a total of
10 bytes of address). You should save this away so that you can
respond to ARP requests that occur later.
- push ( char *buf,
int len, char *addr); The push method will
- Look up the destination IP address
in the ARP table.
- If the address is found, send the
payload untouched to the Ethernet layer, specifying the destination Ethernet address from the
table. You should put 0x800 in the top 16 bits (type field) of the
length to indicate that this is a normal IP packet.
- If the address is not found, send an
ARP packet with the Operation=1 for REQUEST and sleep for 10 seconds (in
practice, you can probably get away with sleeping only 3 seconds).
You indicate that this is an ARP packet by putting the value 0x806
in the top 16 bits of the length parameter.
- If a response to the ARP occurs before the sleep finishes (an
ARP packet is received with Operation=2 for RESPONSE), the ARP table
will be filled in with the correct value.
- When the thread wakes up, it should check the ARP table
again. If the address is still not found, return, otherwise, send
the packet to the destination specified in the ARP table.
- pop ( char *buf,
int len);When this method is called, you should
- See if the top 16 bits of len
is 0x806 (remove these bits and use the bottom 16 bits for the real
length). If so, this is an ARP packet, so check the Operation
field, if is a 1 then it is a request. You should see if the
Target Protocol Address is your IP address. If so, create an ARP
response packet (swap the target and source pairs and change the
OPERATION field to 2 for response). If you are not the target,
ignore it. If you are the target, you should add the source host's
IP and Ethernet address to your ARP table.
- If the top 16 bits of len is
0x800, pass the packet untouched up to the next layer.
Template
The arp framework can be found at ~cs460ta/labs/arp_template (this
path is found when using your account on the cs460 lab machines - just
"cd" to this location). It contains the TA version of physical and
ethernet layers that talk to the real ethernet. It also contains a
template for the arp layer and the test version of internet and main.
The framework will provide you with a physical layer that talks to a
daemon (ether_service) that runs on each machine in the lab. You will
need to use the template versions of the physical layer and ethernet
layer in order to talk through the daemon to the ethernet card. The
traffic you generate in this lab will be sent to the 2nd ethernet card
(eth1) and you will need to select eth1 in the capture window for
ethereal. Your main debugging tool will be to use ethereal to monitor
traffic on this network link.
Passoff:
The passoff procedure will test the following specific items
The main()
code will send a packet from the client to the destination IP
address. On the first send, you should send an ARP packet to get
the destination Ethernet address, after that, packets with that target
IP address will be sent directly to the correct Ethernet address.
The main()
code will then send packets to different IP addresses. Your code
should send another ARP packet when each new IP address is presented,
but should remember which addresses it already knows.
The server code
will send ARP packets to your client with your target IP and you should
respond with your Ethernet address.
Tips:
You will
probably want to turn on "Update list of packets in real time" and
"Automatic scrolling in live capture" in the ethereal capture window so
you can see packets as they arrive. It's also a good idea to turn
off "Enable Name Resolution" since we're using fake addresses in this
lab.
The arguments to the binary are now different. The argments
are (host where daemon is running) (port daemon is listening to) (src
IP address) (src ETH address) (dst IP address) (dst
ETH address) (-c or -s) (-v optional debug flag) (0xff debug
level). The additional arguments were included so that you can run
your code without interfering with other students. Please note
that these are fake IP and ethernet addresses! Pick
IP addresses and Ethernet addresses with the same top bytes as the
example below, then change the bottom
byte between 0 and 200 in order to avoid conflicts with other
students' packets.
Example:
On the machine cs460-7 run
./arp cs460-7 1234 192.168.102.7 00:a0:cc:66:99:33 192.168.102.2
00:a0:cc:66:99:35 -c -v 0xff
On the machine cs460-5 run with exactly the same arguments, except for
the hostname and client flag
./arp cs460-5 1234 192.168.102.7 00:a0:cc:66:99:33 192.168.102.2
00:a0:cc:66:99:35 -s -v 0xff
Type in a test string on the client machine and it should send an
arp packet to the server machine. The IP addresses and
Ethernet addresses you are supplying on the command line do not really
exist so no real machines will respond to them. There are some
real IP addresses hardcoded in main.cc that will test the response of a
real machine. Your code will be answering the ARP on another
machine that has the same fictional IP and Ethernet values.
When the server indicates that you have passed off that part of the lab,
hit the enter key on the server and he will send back a packet to the
client.
You will
always connect to the daemon on port 1234. The daemon is
"ether_service" and you can use "ps -ef | grep service" to make sure it
is running on the machine you are working on. You will
probably want to run this on machines where nobody else is working so
you don't have as much traffic to sort through in the sniffer.
While you are
getting your code working, you will probably want to turn on some
serious debug statements. If you run the lab code with something
like "./arp cs460-7 1234 192.168.102.1 00:a0:cc:66:99:33 192.168.102.2
00:a0:cc:66:99:35 -c -v 0xff" it will turn on a lot of debug in the
lower layers. Bit 0 turns on the physical layer printfs. Bit
1 (0x2) turns on the ethernet debug. Bit 2 (0x4) turns on a printf
when something is not destined for your ethernet address. Bit 3
(0x8) turns on the basic arp debug. Bit 4 (0x10) just shows what
is being put into the arp table.
Run your code, compiled with the versions of main.cc and internet.cc
found in the framework. The lab version of the code can be
run directly from ~cs460ta/labs/arp. The client code should prompt
you for a string to send. This string will be pushed to your arp
code and when the arp response is received from the server (lab version
of the code) the packet should be sent. This string should then
appear on the server window. The client will then send the
characters 0xfeedbeef and this should be displayed on the server
(lab version of the code). The client will then send the
characters 0xfeedbeef to another IP address and you should
generate another ARP. The lab code will respond to this other
address and should print out another passoff message indicating that it
has received the string. You should then press the enter key on
the server and it will send an arp request packet to your client.
If you respond correctly, the server will send 0xfeedbeef back to you
and your code will display a passoff message.
You may want to run additional tests of your own to make sure that
things are working.
The following passoff levels will apply to this lab:
| Passoff
Level |
Behavior |
Points |
| Minimal
Passoff |
At
least one ARP packet is correctly sent and received and the data packet
is then sent to the correct Ethernet destination. |
2
Points |
| Perfect
behavior |
Passes
all tests |
3
Points |