With Network Address Translation (NAT), IP addresses are mapped from one realm to another, in an attempt to provide transparent routing to hosts. Traditionally, NAT devices are used to connect an isolated address realm with private unregistered addresses to an external realm with globally unique registered addresses. There are many variations of address translation. For the project, you are going to implement Basic NAT [4].
Figure 5 demonstrates the usage of Basic NAT in an example scenario. Hosts A and B have private IP addresses 191.68.0.1 and 192.168.0.5, respectively. Private IP addresses are unique within the local network, but not globally. All the packets going from the private network to the Internet have to go through a NAT box. The NAT box is assigned two globally unique IP addresses (145.67.8.3 and 145.67.8.4) for address translation. Assume host A wants to communicate with a host in the Internet that has the globally unique address 198.76.34.2. It generates a packet with this destination address. The source address is set to its private address. When the NAT box receives this packet, it replaces the private source address with the global address 145.67.8.3. Similarly, if host B wants to communicate with a host on the Internet, the NAT box uses 145.67.8.4 as source address for packets coming from B. For IP packets on the return path, a similar address translation is required.
Figure 4 shows where in the IP layer NAT takes place. For this project, we assume that the NAT box has a globally unique IP address for each host in the private network and that the mapping between a private and a global address is static. In your implementation, you need to implement Basic NAT. You do not need to change port numbers in TCP/UDP packets and you do not need to deal with ICMP packets. However, in addition to the source address (or the destination address for the reverse path), it might be required to also modify some other fields in the TCP/UDP/IP header to make end-to-end communication work.
You should write a user program setnat that parses a file containing the mappings from private to public IP addresses. An example entry is given below:
代码语言:javascript复制192.168.0.1 -> 128.2.4.5
The only argument to the program is the name of a file containing the mappings (e.g., setnat -n 1 mapping.txt). To add a mapping to the NAT box from a user program, you need to call Setsockopt() on a routing socket with level IPPROTO_IP and option name IP_NAT_SET. It is up to you to come up with a convenient data structure for the option value. Given this level/option name combination, the kernel will call nat_setsockopt(), where the actual configuration is done. You need to provide the body of this function.
Prototypes of the NAT functions that you need to implement are provided in $PDIR/template/nat.c. When a node boots, it calls nat_init(). If your firewalling implementation requires initialization code, you should place it there.