CSS 432
Program 4: Domain Name Service
Professor Dimpsey
1. Purpose
This assignment is to design and code a program that
enables a server to check the integrity of a client
connection by looking for
IP address spoofing.
Through this assignment, you are going to learn how to use
functions for accessing the
Domain Name System (DNS),
such as getpeername, gethostbyaddr, and
for converting addresses, such as inet_ntoa,
ntohs, and inet_addr.
2. Algorithm
DNS is useful not only for resolving the IP address of a server
to which you would like to connect, 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:
- Use argv[1] in argument as the port to which
spoofcheck.cpp should bind itself.
- Instantiate a TCP socket.
- Go into an infinite loop (while (true) ...) where:
- Accept a new connection from a client through accept().
- Spawn a child process through fork().
The parent closes this connection and
goes back to the top of the loop, whereas the child
continues checking the integrity of this connection.
- Retrieve the client's IP address and port of this connection through
getpeername().
- Retrieve the client's hostent data structure through
gethostbyaddr().
- Retrieve the client's official name, aliases, and registered
IP addresses from the hostent.
- Decide whether this client is a honest or a spoofing client by
matching its IP address retrieved from getpeername()
and the list of addresses retrieved via 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.)
- Terminate this child process.
The following shows an example where spoofcheck was invoked
at csslab4 on port 12345 while three different clients
- 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@csslab4 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!
an 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!
an honest client
client addr = 216.186.72.14 port = 32848
official hostname: metis.uwb.edu
alias: metis
ip address: 216.186.72.14 ... hit!
an honest client
^c
[css432@csslab4 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.
- int
getpeername(int s, struct sockaddr *name, socklen_t *namelen)
retrieves a pointer to information about the IP address (sockaddr name)
of the peer socket in the second argument.
The first argument is the socket file descriptor you have accepted from a client.
The third argument is a pointer to the length of the address name,
whose initial value should be a variable set to sizeof( name ).
Since the function retrieves address information (not a name, strictly speaking),
you may want to use variable names such as clientAddr and addrLen
that better indicate the actual information.
Also, since we are using IPv4, you should declare your name (or clientAddr)
variable of type sockaddr_in rather than sockaddr
(if we were using IPv6, you would use sockaddr_in6).
- struct sockaddr_in
the data structure you will receive
from getpeername(), (e.g., clientAddr in the
example 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()
};
- struct hostent *
gethostbyaddr(const void *addr, int len, int type)
returns a pointer to the entry for a host (hostent) maintained by a DNS server.
The first argument should be an unsigned int addr of
a client IP address string that has been converted into
an unsigned integer through inet_addr().
The second and third arguments should be sizeof(
unsigned int ) and AF_INET respectively.
- struct hostent
the data structure returned by gethostbyaddr().
To retrieve the official name and aliases
of a given host, use the h_name and h_aliases fields.
To convert an address associated with a host, (i.e.,
h_addr_list[i]), use inet_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 */
};
- uint16_t
ntohs(uint16_t netshort)
returns the argument value converted from network to
host byte order. Use this function to obtain a client's port number
from clientAddr.sin_port.
- in_addr_t
inet_addr(const char *cp)
converts a string-typed IP address, in the
standard IPv4 dotted decimal notation, to an integer value suitable
for use as an Internet address.
As noted above, you should use this function to convert the first
argument passed to gethostbyaddr().
- char *
inet_ntoa(struct in_addr in)
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 the
h_addr_list[] array in hostent.
4. Statement of Work
Code spoofcheck.cpp, compile it, and verify your
implementation. Feel free to grab and re-use the code you
created in program 1.
To test your program, run spoofcheck at any of csslab Linux
machines, (say csslab4) and thereafter login to any other machines
where you can initiate a client TCP connection to your
spoofcheck server through telnet. The following shows
an example test plan using the spoofcheck executable
that can be found in the /CSSDIV/classes/432/hw4 directory:
[css432@csslab4 hw4]$ ./spoofcheck 12345
client addr = 10.155.176.20 port = 34433
official hostname: csslab5.uwb.edu
alias: none
ip address: 10.155.176.20 ... hit!
an honest client
The first lines of output above were generated by
testing from a separate xterm (on csslab5) as shown below:
[css432@csslab5 ~]$ telnet csslab4 12345
Trying 10.155.176.19...
Connected to csslab4.uwb.edu (10.155.176.19).
Escape character is '^]'.
Connection closed by foreign host.
You can use PuTTY on a windows computer as well.
Select "Telnet" and specifying the server "csslab4" and port "12345":
Try to establish a TCP connection from at least 3 different
computers on the UWB campus, one of which must be a Windows
machine. Also see what happens when you try to establish connection
from a machine outide the uwb network.
In addition to your programming and verification work,
discuss the following three questions in your report:
- Your server, (actually each server process) terminates a client connection.
Does this server-initiated TCP disconnection cause any potential problems?
Why or why not?
- 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? Why or why not?
- If a client uses a dynamic IP address to be obtained from its DHCP server,
can your server verify this client's integrity? Why or why not?
5. What to Turn in
The homework will be turned in on Canvas.
Criteria |
Percentage |
Documentation/Description of your
spoofcheck.cpp in one page.
| 3 pts (15%) |
Source code: that adheres good
function modularization, coding style, and an appropriate amount of
comments. The source code is graded in terms of
- correct discovery of a client IP address and port through
getpeername(), inet_ntoa() and ntohs(): 4pts
- correct discovery of a client official name, alias, and IP address(es) through the
gethostbyaddr() and hostent: 4pts
|
8 pts (40%) |
Execution output showing your server output for each test case in a file
called hw4.output. Your output must verify the integrity of 3 different client
connections, one of which must be established from a Windows
machine. The output itself receives 1pt and each client verification
receives 1pt. |
4 pts (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 1pt |
5 pts (25%) |
Total |
20 pts (100%) |
6. FAQ
This FAQ page may answer your questions. Click here.