CS 640 Introduction to Computer Networks

 

Programming Assignment 0: Simple Name Server (SNS)

 

Instructions & FAQs

 

Please check this page for FAQs and frequent updates on instructions.  .

 

Testing your program:

 Once you have coded up a client program that meets all the specifications, you can test your program by sending request packets to one of the servers running at the following ports.

 Server IP (common to all servers):  128.105.181.26

 

Returns invalid responses?

Server #

Port #

 

1

5200

*

2

5201

 

3

5202

*

4

5203

 

5

5204

*

6

5205

Please Note:

·       Note that servers 2, 4 and 6 (marked with an * ) return invalid response packet consistently i.e. wrong protocol number. Use these servers to test the robustness of  your client program.

·        The test servers are designed to be running perennially and will not terminate upon received of a client request of type 5.

·        Please ensure that your client program is complete and adheres to all project specifications before sending test packets to the server.

·        For testing purposes, the database used by the server to respond to client requests contains the following records:

Domain Name

IP Address

www.google.com

216.239.39.147

tux21.cs.wisc.edu

128.105.111.121

www.cnn.com

64.236.16.20

monty.cs.wisc.edu

128.105.165.133

nova1.cs.wisc.edu

128.105.119.101

·       
If you encounter any problems while attempting to connect to a particular server, use one of the other specified ports. If none of the servers are accessible, try connecting again after a few minutes. If the problem persists, send email to the TA (yu-chi@cs.wisc.edu)

 
Submission Instructions:

 
·        What to submit:

 

You will need to submit the source code along with a Makefile, located in a directory called p0/. Compact the directory into a single tar.gz file and name it p0.tar.gz. Do not submit object files, or compiled executables.

 

The Makefile should have two rules: clean and all.

clean : will delete previous .o files, executables, etc.

all : should produce a single executable called client.

 

The TA will run the following sequence of operations to execute and test your code:

 

tar xvfz p0.tar.gz

cd p0/

make clean

make all

./client -s <server-name> -p <port> -r <type> -d <data> -t <timeout> -n <seq-no>

 

Please test to make sure that these commands can execute in sequence without any intervention.

 
·        How to submit:

 

First add the following line to your .cshrc.local file (located in your home directory):

set path = ($path /s/handin/bin)

 

Then run the following command at the shell prompt:

source ~/.cshrc.local

 

Finally, to handin your files, enter the following command:

handin -c cs640-1 -a PA0 -d <directory>

where <directory> is the path to the directory where all your files are located.

 

handin will go through the specified directory and hand in all the necessary files.


Frequently Asked Questions:

(1). The client skeleton provided to you has the following statement:

while ((c = getopt (argc, argv, "hs:p:r:a:t:x:")) != -1)

The options in this statement don't match the options specified in your assignment description. Please change the statement to:
while ((c = getopt (argc, argv, "hs:p:r:d:t:n:")) != -1)

(2) The man pages for some of the  functions needed for the assignment are retrieving  documentation for the perl functions first. To change this, please enter the following command at the command prompt:
               
               setenv MANPATH /usr/share/man
      
(3) For running the client, make sure that you provide the integer value of the request type for the -r option.

(4) Constructing the packet -- There are many ways to create a packet. memcpy is one of the safest and easiest ways. Here is a small example how you can use memcpy.
 //2 bytes of protocol
char replyPacket[replysize]; //it will hold the final packet. you will have to compute the size of the packet beforehand. it will be 8+the size of data filed.
unsigned short int n_protocol= htons(640);  // make sure that you convert it into network byte order as the server expects
memcpy(replyPacket, (char *) &n_protocol, sizeof(n_protocol));  //see the man page for memcpy
int offset = sizeof(n_protocol);//should be 16 bits(2 bytes)

// 2 bytes of sequence number
short int seq=10;
short int n_seq_num =htons(seq);
memcpy(replyPacket+offset,(char *) &n_seq_num, sizeof(n_seq_num));
offset += sizeof(n_seq_num);

(4) When you put the hostname in the packet, you should count the \0 in the hostname for the size of packet.

The following is two simple examples for what the payload should look like and what the length should be

1. the host name is tom3.cs.wisc.edu
the payload of sending message should look like this
tom3.cs.wisc.edu_XXX where _ is the '\0' and X is zero padding and the length of the entire packet should be 8 (header) + 20 = 28

2. the host name is foghorn.cs.wisc.edu the payload of sending message should look like this
foghorn.cs.wisc.edu_ where _ is '\0'and length should be 8 + 20 =28

(6) When running the server, the bind(...) fails. You should just try to bind at other port.

(7) Machine IP address: Use ping to find the server's IP address such as ping emperor28.cs.wisc.edu

(8) Endianness issues: there is no ensured endian for your host. The only ensurance you can get is to use htons, htonl, ntohs, ntohl to ensure the proper endian for network and local host. For this project, the process should be like this
a. When local host handles protocol, seq, length, and etc., the orientation of data should be host endian ( big- or small-)
b. Before you send it through network, you should use hton to transform them to network endian
c. When receiving it through network, you should use ntoh to transform them back to host endian before do the necessary process.
For network address and port, they are already in network endian. Thus, you don't need to do any transformation.

(9) For the reserve bit and operation type, you need to use bit wise operator. Please pay attention to the data structure. The left most will be the most significant bit. In this project, Oth bit is the most significant bit.
e.g. char c = 1 i.e. 00000001 and 1 will be in the 7th bit.
a. Example to create and R = 1 and op = 3
R = 1 i.e 00000001 => R = R <<7 i.e. 10000000 (to move 1 from 7th bit i.e. the least significant bit to 0th bit i.e the most significant bit
Similarly,
op = 3 i.e 00000011 => op = op << 4 i.e. 00110000
ToSend = R | op => 00000001 | 00000110 = 10110000
and then you memcpy ToSend into the packet.

b. Decoding: received_combine = 11000000

for decoding R part
#define RMask 10000000
R = RMask & received_part i.e 10000000 => R = R >>7 i.e. 00000001 (to move 1 from 0th bit i.e. the most significant bit to 7th bit i.e the least significant bit

for decoding Op part
#define OpMask 01110000
op = OpMask & received_part = 01000000
op = op >> 4 = 00000100