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