IC221: Systems Programming (SP17)


Home Policy Calendar Units Assignments Resources

Lab 11: Network Addressing

Table of Contents

Preliminaries

Lab Setup

Run the following command

~aviv/bin/ic221-up

Change into the lab directory

cd ~/ic221/lab/11

All the material you need to complete the lab can be found in the lab directory. All material you will submit, you should place within the lab directory. Throughout this lab, we refer to the lab directory, which you should interpret as the above path.

Submission Folder

For this lab, all ubmission should be placed in the following folder:

~/ic221/lab/11

README

In the top level of the lab directory, you will find a README file. You must fill out the README file with your name and alpha. Please include a short summary of each of the tasks and any other information you want to provide to the instructor.

Test Script

You are provided a test script which prints pass/fail information for a set of tests for your programs. Note that passing all the tests does not mean you will receive a perfect score: other tests will be performed on your submission. To run the test script, execute test.sh from the lab directory.

./test.sh

You can comment out individual tests while working on different parts of the lab. Open up the test script and place comments at the bottom where appropriate.

myhost

In this part of the lab you will implement your own version of the host command. Recall that the Unix tool host performs a DNS look up of a domain name to resolve it to the IP address, but as we observed in the previous lesson, a domain name may resolve to multiple IP addresses in both version 4 and version 6 of the IP address specification.

The library function to resolve an domain name to an IP address is getaddrinfo() and the relevant result structure is an struct addrinfo.

struct addrinfo {
          int              ai_flags;  
          int              ai_family;
          int              ai_socktype; 
          int              ai_protocol;
          size_t           ai_addrlen;
          struct sockaddr *ai_addr;
          char            *ai_canonname;
          struct addrinfo *ai_next;
      };

So far, we've discussed the ai_addr, which stores the socket address that we cast to a ipv4 socket, to eventually get the IP address. An interesting aspect of this structure is that it also a node within a linked next. The ai_next field stores a pointer to the next addrinfo which stores other resolved to IP address for the domain. Eventually, ai_next references NULL, which indicates the end of the list. We can now iterate over the linked list of addrinfo's like so:

struct addrinfo * cur_result, *results, hints;
//...

//Convert the hostname to an address
if( (s = getaddrinfo(argv[1], NULL, &hints, &result)) != 0){
  fprintf(stderr, "getaddrinfo: %s\n",gai_strerror(s));
  exit(1);
 }

for(cur_result = result; cur_result != NULL; cur_result = cur_result->ai_next){
  //do something with the current result
 }

Another important aspect of the addrinfo is the ai_protocol which describes how the domain name is resolved based on which application layer protocol we are interested in. For example, often domains have different IP addresses for web traffic and email, and this difference is represented in the ai_protocol field. Since we are only interested in the primary resolution of the domain, we can check for that by comparing against the constant IPPROTO_TCP since we want IP address accepting TCP connections.

cur_result->ai_protocol == IPPROTO_TCP

The last aspect of the addrinfo structure to consider is that ai_family, which describes the kind of address was resolved. This could either be IPv4 (AFINET) or IPv6 (AFINET6). We are primarily concerned with IPv4, so you can compare ai_family to AF_INET to ensure you are only access resolution of the right IP address:

cur_result->ai_family == AF_INET

For both of these options, you could specify that choice in the hint addrinfo when making the getaddrinfo(). Then, getaddrinfo() will only return results that fit those requirements.

Task 1: myhost

For this task, change into the myhost directory, where you will find two files:

  • myhost.c : myhost source file which you will complete
  • Makefile : to compile your program

Your goal is to complete the myhost program so that it meets the following specification.

  1. For a given domain name, it must resolve all the IP addresses associated with protocol 0 for that domain.
  2. It should print out the results as similarly to the Unix host command as possible.
  3. It should only consider IPv4 addresses

Below is some sample output (not the IP address may differ between runs):

aviv@saddleback: myhost $ ./myhost facebook.com
facebook.com has address 31.13.69.228
facebook.com has IPv6 address 2a03:2880:f103:83:face:b00c:0:25de
aviv@saddleback: myhost $ ./myhost yahoo.com
yahoo.com has address 98.139.183.24
yahoo.com has address 206.190.36.45
yahoo.com has address 98.138.253.109
aviv@saddleback: myhost $ ./myhost google.com
google.com has address 172.217.7.206
aviv@saddleback: myhost $ ./myhost microsoft.com
microsoft.com has address 191.239.213.197
microsoft.com has address 104.40.211.35
microsoft.com has address 104.43.195.251
microsoft.com has address 23.100.122.175
microsoft.com has address 23.96.52.53
aviv@saddleback: myhost $ ./myhost www.seas.upenn.edu
www.seas.upenn.edu has address 158.130.68.91
aviv@saddleback: myhost $ ./myhost bad.bad.bad
getaddrinfo: Name or service not known
aviv@saddleback: myhost $ ./myhost 
getaddrinfo: Name or service not known

EXTRA CREDIT (3 points): Add the ability for your myhost program to resolve the IPv6 address with the same format as host. For example:

aviv@saddleback: myhost $ ./myhost www.seas.upenn.edu
www.seas.upenn.edu has address 158.130.68.91
www.seas.upenn.edu has IPv6 address 2607:f470:8:64:5ea5::9
aviv@saddleback: myhost $ ./myhost yahoo.com
yahoo.com has address 98.139.183.24
yahoo.com has address 206.190.36.45
yahoo.com has address 98.138.253.109
yahoo.com has IPv6 address 2001:4998:58:c02::a9
yahoo.com has IPv6 address 2001:4998:c:a06::2:4008
yahoo.com has IPv6 address 2001:4998:44:204::a7
aviv@saddleback: myhost $ ./myhost google.com
google.com has address 172.217.7.206
google.com has IPv6 address 2607:f8b0:4004:801::200e

Check out the man pages for inet_ntop() and inet_pton() for some useful details.