CSS 432
Program 4: Domain Name Service

Professor: Munehiro Fukuda
Due date: See the syllabus


1. Purpose

This assignment is to design and code a spoof-checking program that enables a server to check the integrity of a client connection. Through this assignment, you are going to learn how to use DNS-related and address-conversion functions such as getpeername, gethostbyaddr, inet_ntoa, ntohs, and inet_addr.

2. Algorithm

DNS is useful not only for resolving the IP address of a server you would like to connect to but also for verifying the integrity of a client that has contacted to your server. Since the client information within an IP packet includes only its source address and port number, it is impossible to find who actually sent this packet. A malicious client can even change its IP address and pretend to be someone else. A solution to block out such a spoofing client is to refer its IP address to a DNS server that retrieves this client's official host name, aliases, and registered IP addresses. Based on this concept, our spoofcheck.cpp program should behave as follows:
  1. Use main( )'s argv[1] argument as an IP port to which spoofcheck.cpp should bind itself.
  2. Instantiate a TCP socket.
  3. Go into an infinite while( ) loop where:
    1. Accept a new connection from a client through accept( ).
    2. Fork a child process. The parent closes this connection and goes back to the top of the while( ) loop, whereas the child continues checking the integrity of this connection.
    3. Retrieve the client's IP address and port of this connection through getpeername( ).
    4. Retrieve the client's hostent data structure through gethostbyaddr( ) .
    5. Retrieve the client's official name, aliases, and registered IP addresses from the hostent.
    6. Decide whether this client is a honest or a spoofing client by matching its IP address retrieved from getpeername( ) and those retrieved from gethostbyaddr( ). (In other words, if you confirm that the client's IP address of this connection matches one of the addresses listed in hostent, you can trust this client.)
    7. Terminate this child process.
The following shows an example where spoofcheck was invoked at uw1-320-20 on port 12345. Three different clients such as perseus, uw1-331-pc01, and metis accessed this spoofcheck server. The server printed out the client address and port retrieved from getpeername( ) as well as its official hostname, aliases, and a list of IP addresses retrieved from gethostbyaddr( ).
[css432@uw1-320-20 hw4]$ ./spoofcheck 12345
client addr = 216.186.75.3 port = 39329
official hostname: perseus.uwb.edu
alias: none
ip address: 216.186.75.3 ... hit!
a honest client

client addr = 216.186.75.144 port = 4252
official hostname: uw1-331-pc01.uwb.edu
alias: none
ip address: 216.186.75.144 ... hit!
a honest client

client addr = 216.186.72.14 port = 32848
official hostname: metis.uwb.edu
alias: metis
ip address: 216.186.72.14 ... hit!
a honest client

^c
[css432@uw1-320-20 hw4]$ 

3. Required Data Structures and Functions

To implement this spoofcheck program, you need to use the following IP-related data structures and DNS-related/address-conversion functions:
  1. getpeername( ): gets the name of the peer socket. The first argument is the socket you have accepted from a client. The second and third arguments are struct sockeaddr_in clientAddr; and socklen_t addrLen = sizeof( chientAddr ); respectively. Note that clientAddr and addrLen are whatever you can name. The clientAddr structure includes the client's address information.
  2. struct sockaddr_in: is the data structure you will receive from getpeername, (i.e., clientAddr in the above). To retrieve a client's ip address and port (in sin_addr and sin_port), use inet_ntoa( ) and ntohs( ) respectively.
    #include <netinet/in.h>
    
    struct sockaddr_in {
        short            sin_family;   // e.g. AF_INET
        unsigned short   sin_port;     // e.g. htons(3490)
        struct in_addr   sin_addr;     // see struct in_addr, below
        char             sin_zero[8];  // zero this if you want to
    };
    
    struct in_addr {
        unsigned long s_addr;  // load with inet_aton()
    };
    
  3. gethostbyaddr( ): retrieves information about a given host from a DNS server. The first argument is unsigned int addr of a client IP address that can be obtained by converting its string-typed IP address into an unsigned integer through inet_addr. The second and third arguments are sizeof( unsigned int ) and AF_INET respectively. The gethostbyaddr returns a pointer to a hostent data structure.
  4. struct hostent: is the data structure you will receive from gethostbyaddr( ). To retrieve the official name and aliases of a given host, access h_name and h_aliases. To retrieve the list of addresses from a DNS server, (i.e., h_addr_list[i]), use int_ntoa( ).
    #include <netdb.h>
    struct	hostent {
    	const char *h_name;	/* official name of host */
    	char	**h_aliases;	/* alias list */
    	short	h_addrtype;	/* host address type */
    	short	h_length;	/* length of address */
    	char	**h_addr_list;	/* list of addresses from name server */
    #define	h_addr	h_addr_list[0]	/* address, for backward compatibility */
    };
    
  5. ntohs( ): returns the argument value converted from network to host byte order. Use this function to obtain a client's port number from cleintAddr.sin_port.
  6. inet_addr( ): converts a string-typed IP address, in the standard IPv4 dotted decimal notation, to an integer value suitable for use as an Internet address. Use this function to create the first argument passed to gethostbyaddr.
  7. inet_ntoa( ): converts the Internet host address specified by its argument struct in_addr in to a string in the Internet standard dot notation. Use this function to obtain a string-typed IP address from clientAddr.sin_addr and struct hostent's h_addr_list[] array.
For details, read the Linux manual by typing:
man getpeername
man gethostbyaddr
man inet_ntoa
man ntohs
man inet_addr

4. Statement of Work

Code spoofcheck.cpp, compile it, and verify your implementation. You may use HW1's Socket.h and Socket.cpp. Code everything just in spoofcheck.cpp. For compilation, type:
 
g++ spoofcheck.cpp Socket.cpp -o spoofcheck 
To test your program, run spoofcheck at any of uw1-320 Linux machines, (say uw1-320-20) and thereafter login any other machines where you will initiate a client TCP connection to your spoofcheck server through telnet. The following shows an example test plan:
[css432@uw1-320-20 hw4]$ ./spoofcheck 12345
client addr = 216.186.75.196 port = 34433
official hostname: uw1-320-21.uwb.edu
alias: none
ip address: 216.186.75.196 ... hit!
a honest client

[css432@uw1-320-31 ~]$ telnet uw1-320-20 12345
Trying 216.186.75.195...
Connected to uw1-320-20.uwb.edu (216.186.75.195).
Escape character is '^]'.
Connection closed by foreign host.
Try to establish a TCP connection from at least three different computers on the UWB campus, one of which must be a Windows machine. To use telnet from Windows, open a command-prompt window and type:
c:\>telnet uw1-320-20 12345
Note that you cannot establish a TCP connection to UWB from off-campus through any other ports than the well-known system ports such as 22 and 80. Therefore you don't have to and cannot conduct your verification from off-campus. In addition to your programming and verification work, discuss about the following three questions in your report:
  1. Your server, (actually each server process) terminates a client connection. Doesn't this server-initiated TCP disconnection cause any problem?
  2. If a client resides in a private address domain and thus tries to connect to your spoofcheck server through NAT, can your server verify this client's integrity?
  3. If a client uses a dynamic IP address to be obtained from its DHCP server, can your server verify this client's integrity?

5. What to Turn in

The homework is due at the beginning of class on the due date. You have to turn in the following materials to CollectIt. No email submission is accepted.
Criteria Percentage
Documentation of your spoofcheck.cpp in one page. 3pts(15%)
Source code: that adheres good function modularization, coding style, and an appropriate amount of comments. The source code is graded in terms of (1) correct discovery of a client IP address and port through getpeername, inet_ntoa and ntohs (3pts), (2) correct discovery of a client official name, alias, and IP address(es) through the gethostbyaddr function and the hostent structure (3pts), and (3) comments (1pt). 7pts(35%)
Execution output such as a snapshot of your display/windows. Type import -window root X.jpeg; lpr -Puw1-320-p1 X.jpeg on a uw1-320 Linux machine. Or, submit contents of standard output that has been redirected to a file. Your output must verify the integrity of three different client connections, one of which must be established from a Windows machine. The output itself receives 1pt and each client verification receives 1pt. 4pts(20%)
Discussions: should be given in terms of three items: (1) a server-initiated TCP disconnection, (2) a client's connection through NAT, and (3) a client's DHCP-generated dynamic IP address, each receiving 2pts. 6pts(30%)
Total 20pts(100%)

6. FAQ

This FAQ page may answer your questions. Click here.