NAT Lab
Background:
In this lab, you will modify the IP layer to perform network address
translation. Network address translation (NAT) is used to improve
security and to enable more flexibility in the management of
machines. You may also want to take a look at some basic NAT
documentation (
http://www.cisco.com/en/US/tech/tk648/tk361/technologies_tech_note09186a0080094831.shtml ).
Specifications:
The IP layer object will be that same as the IP lab, with the
exception of the NAT functionality in the pop method:
- 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. You should save
this away so that you can send it as the source address in your packets.
- push ( char *buf,
int len, char *addr);The push method will
- Look at the len field.
If it is greater than 30 bytes, then you should fragment the
segment. You will send the first packet with the M bit on and only
the last packet of the segment will have the M bit off. Remember
that the segment must be fragmented on 8 byte boundaries because of the
Offset field.
- pop ( char *buf,
int len);When this method is called, you should
- Make sure that your machine is the
destination of the packet; if not, process it through the NAT scheme
described below.
- Use the ident field to identify
which segment it is associated with. If this is a new ident value,
allocate a record-keeping structure for this segment.
- See if the M bit is on. If so,
put the fragment in the correct offset in the segment (you will need to
declare an array to store the fragments in as they are received).
- If the M bit is not on, then you can
determine the total length of the segment (Offset*8+length-HLen*4) to
pass up to the next layer.
- When all of the holes (fragments)
have been received, pass the segment up to the next layer.
- NAT scheme
- If the destination address does
not match your configured IP address for your stack, use the
proxy_subnet_mask to determine if the address is in the
proxy_input_subnet. The table structure defined in nat.h and declared in
main.cc will give you the subnet and mask values. If there is a
match, change the network part of the source IP address to have the
proxy_output_src_subnet and the network part of the destination
addresses to use the proxy_output_dest_subnet, leaving the host part of
the address unchanged. You will need to recompute the checksum
before sending the packet out since the addresses have changed.
You may want to change the values in the table if you are conflicting
with other people's labs.
- If the destination address doesn't
match anything that you have configured, discard it.
struct nat {
unsigned char proxy_input_subnet[IP_ADDRESS_LEN];
unsigned char proxy_output_src_subnet[IP_ADDRESS_LEN];
unsigned char proxy_output_dest_subnet[IP_ADDRESS_LEN];
unsigned char proxy_subnet_mask[IP_ADDRESS_LEN];
}
For example, if the following NAT table were compiled into main.cc
| proxy_input_subnet |
proxy_output_src_subnet |
proxy_output_dest_subnet |
proxy_subnet_mask |
| 192.168.102.16 |
192.168.102.32 |
192.168.102.240 |
255.255.255.240 |
| 192.168.102.32 |
192.168.102.16 |
192.168.102.240 |
255.255.255.240 |
- Push the packet back down.
- You should also respond to ARP
requests for any address that matches the proxy_input_subnet, responding
with your configured ethernet address.
- The following example should
illustrate the process:
- Your switch is running on cs460-3 (192.168.102.243)
- From cs460-2 (192.168.102.242) you run "ping -n
192.168.102.17".
- cs460-2 will then issue a ARP request for
192.168.102.17. Since this machine (17) does not really exist, it
will not respond to the ARP request.
- Your NAT program will mask (AND) this address
(192.168.102.17) with the proxy_subnet_mask (255.255.255.240) to get
(192.168.102.16) which is in your NAT table.
- Your ARP layer should then respond to the ARP request,
using the destination protocol address (192.168.102.17) in the request
ARP packet as the source protocol address in the response packet your
ARP code generates. The source hardware address should be the ethernet
address configured in the init routine for your ARP layer. The
destination protocol and hardware addresses in the response ARP packet
should be identical to the source protocol and hardware addresses in the
request ARP packet.
- Since this is one of your proxy_input_subnets, you will
perform the translation.
- Change the source address from 192.168.102.242 to
192.168.102.34
- source host = (ipaddress AND ( INVERSE
proxy_subnet_mask)
- source host = 192.168.102.242 &
~255.255.255.240) = 2
- add the host to the proxy_output_src_subnet
192.168.102.32 + 2
- Change the destination address from 192.168.102.17 to
192.168.102.241
- dest host = (ipaddress AND ( INVERSE
proxy_subnet_mask)
- dest host = 192.168.102.17 & ~255.255.255.240)
= 1
- add the host to the proxy_output_dest_subnet
192.168.102.240 + 1
- Recalculate the checksum
- Push the IP packet back down (this may generate a ARP
request for the destination machine)
- cs460-1 (192.168.102.241) will respond to the ping packet
and will send the response back to the source address in the IP packet
(192.168.102.34).
- Your switch will mask this address with the
proxy_subnet_mask and finds that this is host number 2 in subnet
192.168.102.32. Since this is one of your proxy_input_subnets, you
will perform the translation.
- Change the source address from 192.168.102.241 to
192.168.102.17
- Change the destination address from 192.168.102.34 to
192.168.102.242
- Recalculate the checksum
- Push the IP packet back down (this may generate a ARP
request for the destination machine)
You don't need the TA version of the code for the NAT
features. If you want an example of how the NAT process works, you can
use the lab code to generate an ethereal trace. The TA version of the lab code uses different NAT tables, so
dont try the following steps with your own code. The lab code will
forward using NAT if you follow the following process
- DONT TRY THESE STEPS WITH YOUR CODE, IT ONLY WORKS WITH THE TA CODE
- start up the lab code on cs460-3
- run "ping -n 192.168.102.66" from cs460-5
- cs460-6 should respond to the ping and send the response
to 128.168.102.67
- the labcode NAT will then send the response to cs460-5
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. Do not enable
name resolution.
- You should use ping -n so that ping doesnt do name
resolution.
- Use different IP addresses and subnet masks than those
specified in this lab writeup. If you use the same values, other
student's code will respond to your arp requests and you will become
confused.
In order to keep you from using the same IP addresses as other
students in the class, you could use the following values at random.
| proxy_input_subnet |
proxy_output_src_subnet |
proxy_output_dest_subnet |
proxy_subnet_mask |
| 192.168.102.48 |
192.168.102.64 |
192.168.102.240 |
255.255.255.240 |
| 192.168.102.64 |
192.168.102.48 |
192.168.102.240 |
255.255.255.240 |
Ping 192.168.102.50 to get to machine cs460-2
| proxy_input_subnet |
proxy_output_src_subnet |
proxy_output_dest_subnet |
proxy_subnet_mask |
| 192.168.102.80 |
192.168.102.96 |
192.168.102.240 |
255.255.255.240 |
| 192.168.102.96 |
192.168.102.80 |
192.168.102.240 |
255.255.255.240 |
Ping 192.168.102.82 to get to machine cs460-2
| proxy_input_subnet |
proxy_output_src_subnet |
proxy_output_dest_subnet |
proxy_subnet_mask |
| 192.168.102.112 |
192.168.102.128 |
192.168.102.240 |
255.255.255.240 |
| 192.168.102.128 |
192.168.102.112 |
192.168.102.240 |
255.255.255.240 |
Ping 192.168.102.114 to get to machine cs460-2
| proxy_input_subnet |
proxy_output_src_subnet |
proxy_output_dest_subnet |
proxy_subnet_mask |
| 192.168.102.144 |
192.168.102.160 |
192.168.102.240 |
255.255.255.240 |
| 192.168.102.160 |
192.168.102.144 |
192.168.102.240 |
255.255.255.240 |
Ping 192.168.102.146 to get to machine cs460-2
| proxy_input_subnet |
proxy_output_src_subnet |
proxy_output_dest_subnet |
proxy_subnet_mask |
| 192.168.102.176 |
192.168.102.192 |
192.168.102.240 |
255.255.255.240 |
| 192.168.102.192 |
192.168.102.176 |
192.168.102.240 |
255.255.255.240 |
Ping 192.168.102.178 to get to machine cs460-2
- if you want to clear the ARP table on a machine run "ifdown eth1; ifup eth1". This will bring the interface down and up and will clear the arp cache
- Please note that if you want this to work using these or different numbers for the nat table IP addresses, you will need to modify the #defined values at the top of main.cc.
- You only need to run one copy of your code as server (with
the -s flag). There is no passoff code for this lab except for the
ping command.
Example:
The arguments to the binary are the same as ARP. The arguments are
(host where daemon is running[this machine]) (port daemon is listening
to[1234]) (src IP address) (src ETH address) (dst IP address) (dst
ETH address) ( -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. Pick IP addresses and Ethernet
addresses with the same top bytes as this example, then change the
bottom byte to a value between 0 and 200.
It doesnt matter what IP addresses you assign to run the ip layer for this lab. You could use the following line to start your code, but the IP addresses dont matter. The MAC addresses dont matter either, pick something that you think is unique.
On the machine cs460-7 run
./ip cs460-7 1234 192.168.102.7 00:a0:cc:66:99:33 192.168.102.2 00:a0:cc:66:99:35 -s -v 0xff
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 "./ip cs460-7 1234 192.168.102.1 00:a0:cc:66:99:33
192.168.102.2 00:a0:cc:66:99:35 -s -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.
Other Changes:
In addition to changing internet.cc, you will need to
change your arp.cc to make NAT work. You should respond to the
ARP if any of the proxy_input_subnet values match the dst address
of the packet masked with the subnet mask. You should respond with
the same ethernet address you would for a normal ARP.
Passoff:
The TA
will ping one of the machines in your NAT table subnet
(proxy_input_subnet) from one of the real machines in the lab. If
all goes well, the ping should be successful and the response should
proceed through your NAT table as well. In essence, ping should
not be able to detect that you are doing the translation. Be
aware that the TA may ping the selected machine using either(or both)
of your subnets (i.e. test your code to make sure you can use all the
entries in your NAT Table)
The following passoff levels will apply to this lab:
| Passoff
Level |
Behavior |
Points |
| Minimal
Passoff |
The ping packet reaches the correct machine |
2
Points |
|
NAT |
Ping does not notice your NAT presence |
8 Points |