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 completeMakefile
: to compile your program
Your goal is to complete the myhost
program so that it meets the
following specification.
- For a given domain name, it must resolve all the IP addresses associated with protocol 0 for that domain.
- It should print out the results as similarly to the Unix
host
command as possible. - 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.