30 things Girls Think Guys Should Know
1. Don't ever lie to us; we always find out.
2. We don't enjoy talking dirty to you as much as you enjoy listening.
3. Don't say you understand when you don't.
4. Girls are petty; get over it.
5. You don't have PMS; don't act like you know what it's like.
6. Saying something sweet might get you off the hook; doing something sweet will always get you off the hook.
7. If you talk about having a big dick; we know you don't.
8. Size does matter.
9. We don't like it when you act like Mr. Big; we like it when you are Mr. Big.
10. A system in your car only impresses your homeboys.
11. No matter what you say, your ex-girlfriend is a ho.
12. It's good to be sensitive, sometimes.
13. If you did something wrong or even if you didn't, apologize.
14. Be spontaneous; dinner and a movie won't always cut it.
15. We are self-conscious by nature; we can't help it.
16. We are drama queens.
17. Fashion police do exist.
18. Don't ask us to give head; if you are nice you just might get it.
19. We absolutely do not care about monster trucks, car systems, paintball, or anything else you and your friends talk about.
20. Hugs and kisses must be given at all times.
21. We don't shave our legs every day; get over it.
22. Don't make bets about us; we always find out.
23. Shave; no matter how cool you think it looks, we hate it.
24. Even is you think it is cool to burp, fart, or emit other strange gases from your body, it is not.
25. Don't compare our breasts with Pamela Anderson's; hers are fake.
26. It is not cool to shoot snot rockets.
27. We are beautiful, but make-up helps.
28. We will always think we are fat, so humor us and tell us we aren't.
29. You can shoot hoops, score a goal, knock down big fat guys, and hit a little baseball with a stick, so why the hell can't you piss in the toilet and not on it.
30. Most importantly: we are always right; so don't forget it.
Friday, December 19, 2008
top most reply of a girl, when you propose her...
top most reply of a girl, when you propose her...
Here are the top most reply of a girl, when you propose her...
1) Nahi........ ......... ???
2) Chiiiii..... Kitne gande vichar hain tumhare..... ..
3) Maine tumhe sirf ek acche dost ki nazar se dekha hai ....
4) Mera pehle se ek boyfrnd hai....
5) Main in baton pe vishwas nahi karti, apne padhai pe dhyaan lagao...
6) tum abhi tak mujhe jaante kahan ho ?Yeh shayad infatuation hai....
7) Tumhara bank balance kitna hai…??
8) Magar last year to Maine tumhe raakhi baandhi thi ..hai
naa..bhaiyya. .??
9) Mein abhi is relation ke liye mentally prepared nahi hoo....
10) Mein apne dady se pooch ke tumhe kaal answer karu…??
11) Itni is baat kehne ke liye itni der lagaa di??
12) Ye donon ke dil me hai na, to phir kya kehna!!
13) Sorry
14) "……Apna chehra kabhi aayine me dekha hai….. L………… "
15) "Main toh tumhe apna Bhai maanati hu"
16) "Yes .. I too like you … (but hope you don't cheat on me ) " …
(Which guys most oftenly do )
17) Phele kyon nahi bataya AB tum late ho gaye ..
18) Tum agar pehle mile hote to sochti.
19) Tumhari himmat kaise hui mere baare mein aisa sochne ki…
(probably followed by a slap)
20) Girl: mujhe sochna ka wakt do…
Guy: kitna wakt???(with hope)
Girl: saat janam
21) Mai ek shaadi shuda ladki hu ;-)
22) Mein tumhare chotte bhai se pyaar karti hoon…
23) Now that's a real tragedy….
Girl: Hee hee ……hee hee hee…..hee ….hee……hee…… Hee hee ……hee hee
hee…..hee ….hee……hee……
24) Boy: I love U!
Gal: I don't think ABT all this before marriage.
25) Keep loving I don't care.
26) Tum mere liye kya kar sakte ho…
27) Kaun as number hai mera tumhare proposals ki history mein. Ha
ha ha ha….
28) tumhe is nazar se kabhi dekha nahi
29) tumhare barre mein kabhi aisa socha nahi
30) mummy se pooch kar bataungi
31) mere bhaiyya se baat kar lo , who hi tumhe samajhayenge
32) Knyo, Tina NE "No" bola?
33) Lekin tum to Mina ke piche pade the, Kya usne thappad mara?
34) Kitne time ke liye -???
35) Worst one-- Jo bhi bolna hai jaldi bolo mera beta school se aata
hoga..
36) Thanks. I love you, too.
37) Boy :- Sonya, I love U…..
Gal :- Sorry , Next 3 Months tak Waiting List chal rahi hai….
38) "What?"
39) "Let's just stay away from this"
40) My friend in college got one classic reply … "I THINK I'M
ENGAGED"
41) "I think, I will have better options in future ..."
42)Mujhe tumse is baare mein koi baat nahi karni, then she starts
ignoring, phir bhi nahi sudhare then she threatens via some common
friends.
43) My Boy friend is very short Tempered. Beware of it.
44) like you as a friend but I never thought about us like this…cant
we be just good friends for ever
45) Actually my younger sis likes you a lot. ..
46) My mummy does not like your family (if the family knows each
other.) ..
47) "Why me?..Tumne mere meih essa kya dekha?..."she wants you to
list down all the Good qualities that you even might have not seen in
her. ...
48) SLAP !! ACTIONS SPEAK LOUDER THAN WORDS....it is said ..
49)hehe I didn't expect that from you....
50)nice joke ...
51)tum ladke kuchh or nahi soch sakte jaha ladki dekhi fisal
gaye.....
52)achha tum bhi meine socha sirf harsh,nikhil, ravi, etc etc ko hi
mujhme interest hai ..... And then walks on.......... ...
53)tumhe to purpose karna bhi nahi aata.... Peheli bari hai kya?? Koi
baat nahi mein batati Hun ???...
Here are the top most reply of a girl, when you propose her...
1) Nahi........ ......... ???
2) Chiiiii..... Kitne gande vichar hain tumhare..... ..
3) Maine tumhe sirf ek acche dost ki nazar se dekha hai ....
4) Mera pehle se ek boyfrnd hai....
5) Main in baton pe vishwas nahi karti, apne padhai pe dhyaan lagao...
6) tum abhi tak mujhe jaante kahan ho ?Yeh shayad infatuation hai....
7) Tumhara bank balance kitna hai…??
8) Magar last year to Maine tumhe raakhi baandhi thi ..hai
naa..bhaiyya. .??
9) Mein abhi is relation ke liye mentally prepared nahi hoo....
10) Mein apne dady se pooch ke tumhe kaal answer karu…??
11) Itni is baat kehne ke liye itni der lagaa di??
12) Ye donon ke dil me hai na, to phir kya kehna!!
13) Sorry
14) "……Apna chehra kabhi aayine me dekha hai….. L………… "
15) "Main toh tumhe apna Bhai maanati hu"
16) "Yes .. I too like you … (but hope you don't cheat on me ) " …
(Which guys most oftenly do )
17) Phele kyon nahi bataya AB tum late ho gaye ..
18) Tum agar pehle mile hote to sochti.
19) Tumhari himmat kaise hui mere baare mein aisa sochne ki…
(probably followed by a slap)
20) Girl: mujhe sochna ka wakt do…
Guy: kitna wakt???(with hope)
Girl: saat janam
21) Mai ek shaadi shuda ladki hu ;-)
22) Mein tumhare chotte bhai se pyaar karti hoon…
23) Now that's a real tragedy….
Girl: Hee hee ……hee hee hee…..hee ….hee……hee…… Hee hee ……hee hee
hee…..hee ….hee……hee……
24) Boy: I love U!
Gal: I don't think ABT all this before marriage.
25) Keep loving I don't care.
26) Tum mere liye kya kar sakte ho…
27) Kaun as number hai mera tumhare proposals ki history mein. Ha
ha ha ha….
28) tumhe is nazar se kabhi dekha nahi
29) tumhare barre mein kabhi aisa socha nahi
30) mummy se pooch kar bataungi
31) mere bhaiyya se baat kar lo , who hi tumhe samajhayenge
32) Knyo, Tina NE "No" bola?
33) Lekin tum to Mina ke piche pade the, Kya usne thappad mara?
34) Kitne time ke liye -???
35) Worst one-- Jo bhi bolna hai jaldi bolo mera beta school se aata
hoga..
36) Thanks. I love you, too.
37) Boy :- Sonya, I love U…..
Gal :- Sorry , Next 3 Months tak Waiting List chal rahi hai….
38) "What?"
39) "Let's just stay away from this"
40) My friend in college got one classic reply … "I THINK I'M
ENGAGED"
41) "I think, I will have better options in future ..."
42)Mujhe tumse is baare mein koi baat nahi karni, then she starts
ignoring, phir bhi nahi sudhare then she threatens via some common
friends.
43) My Boy friend is very short Tempered. Beware of it.
44) like you as a friend but I never thought about us like this…cant
we be just good friends for ever
45) Actually my younger sis likes you a lot. ..
46) My mummy does not like your family (if the family knows each
other.) ..
47) "Why me?..Tumne mere meih essa kya dekha?..."she wants you to
list down all the Good qualities that you even might have not seen in
her. ...
48) SLAP !! ACTIONS SPEAK LOUDER THAN WORDS....it is said ..
49)hehe I didn't expect that from you....
50)nice joke ...
51)tum ladke kuchh or nahi soch sakte jaha ladki dekhi fisal
gaye.....
52)achha tum bhi meine socha sirf harsh,nikhil, ravi, etc etc ko hi
mujhme interest hai ..... And then walks on.......... ...
53)tumhe to purpose karna bhi nahi aata.... Peheli bari hai kya?? Koi
baat nahi mein batati Hun ???...
Thursday, December 18, 2008
TELNET
Documents to read:
Manuals of telnetd(8),telnet(1),issue.net(5),tcpd(8)
and hosts_access(5).
Square brackets are used to separate keywords, such as filenames,
programs names etc etc from lines of text. They have no other meaning.
A TELNET server, with minimal configuration, is to be used in this
experiment.
Create a directory named [telnet], in your home directory.
$ cd <-- puts you in your [home] directory
$ mkdir telnet
$ cd telnet
Installations are to be carried out from this directory. Binary
packages are to be installed. It is also possible to compile from
source code. Such source code may be down-loaded from Internet.
This experiment is to be carried out in Debian Linux platform. Some
Debian specific commands such as [dpkg], [dselect] etc etc have to be
used for software installation and removal. Other distributions have
similar commands of their own. Redhat Linux used [rpm] command.
The following command lists the softwares installed in your host.
$ dpkg -l
The output may be examined one screen at time
$ dpkg -l | more
If the name of the software is known partially it may be checked
$ dpkg -l | grep pyth
Find out the [telnet] related softwares installed in your host
$ dpkg -l | grep telnet
Typical output might be:
ii telnet 0.17-18woody2 The telnet client.
ii telnetd 0.17-18woody2 The telnet server.
The above lines indicate that [telnet] client and [telnet] servers are
installed in your host.
The status of the installed software can be checked.
Check the status of [telnet] client program. Output is not shown.
$ dpkg --status telnet
Check the status of [ telnetd ]. This is the server program. Output is
not shown.
$ dpkg --status telnetd
Test [telnetd] and [telnet] programs in your host
$ telnet 127.0.0.1
You may login in any user account if password is known.
As this experiment is on installation, the installed packages are to
be removed and then reinstalled.
Note: Installation and removal of software needs [root] privilege.
Remove the TELNET client program [telnet]
# dpkg -r telnet
Now the following command should fail
$ telnet 127.0.0.1
Check the [telnet] related installed packages.
$ dpkg -l | grep telnet
Output might be:
rc telnet 0.17-18woody2 The telnet client.
ii telnetd 0.17-18woody2 The telnet server.
The [ telnet ] program was removed but its configuration file was not
removed. Remove the configuration file.
# dpkg --purge telnet
Check the [telnet] related installed packages.
$ dpkg -l | grep telnet
Output might be:
ii telnetd 0.17-18woody2 The telnet server.
Check the status of [telnet] client program. Output is not shown.
$ dpkg --status telnet
Remove TELNET server program with its configuration file/files.
# dpkg --purge telnetd
Check the [telnet] related installed packages.
$ dpkg -l | grep telnet
Copy [ telnet ] and [ telnetd ] binary packages in your [ telnet ]
directory. You may use NFS or FTP for copying.
The package names might be
telnet_0.17-18woody2_i386.deb
and telnetd_0.17-18woody2_i386.deb
Note: The files are also available in first CD of a set of seven CDs.
These CDs are kept in the laboratory.
Install the TELNET client program
# dpkg -i telnet_0.17-18woody2_i386.deb
Check status of [telnet]
$ dpkg --status telnet
At present the TELNET client program is installed. Next command should
fail, as there is no TELNET server running on this host
$ telnet 127.0.0.1
However the client program can be used to access TELNET server running
on other host. Replace 192.16.5.251 with a suitable address.
$ telnet 192.16.5.251
Install the TELNET server program
# dpkg -i telnetd_0.17-18woody2_i386.deb
Check status of [telnetd]
$ dpkg --status telnetd
Find out where the executable(binary) of [telnetd] is installed
$ whereis -b in.telnetd
Location of [in.telnetd] -->
Briefly read manual of the TELNET server
$ man 8 telnetd
From the manual we find that the file [/etc/issue.net] is a text file
which contains a message or system identification to be printed before
the login prompt of a [telnet] session.
To know about the syntax of the file [ /etc/issue.net ], its manual is
consulted.
$ man 5 issue.net
A new [ issue.net ] is to be prepared, to provide the following to a
[telnet] client:
Welcome message
System node name (FQDN)
Current time and date
Name of the operating system and OS release name
Machine (hardware) type
Before modification, the original file is saved with a distinctive
extension for later identification.
$ cp /etc/issue.net ./issue.net-$USER-$( /bin/date +%H-%M )
Note the name of the saved file
$ ls -l | grep issue
Name of saved file-->
Edit [/etc/issue.net]
# nano /etc/issue.net
The file should contain the following text. Replace Sumit with your
name.
-------- /etc/issue.net --------
Welcome to Sumit's TELNET server
Terminal -----> %t
Server name --> %h
Date & time --> %d
OS -----------> %s %r
Hardware -----> %m
--------------------------------
Save the file.
Request two of your friends to [telnet] to your host. 192.169.5.146 is
assumed to be your IP address.
friend1 $ telnet 192.169.5.146
friend2 $ telnet 192.169.5.146
They should get the above information.
A server program may be kept running on a host. Such servers are
called stand-alone servers. Frequently used servers, such as [ named ]
( name server ), [ exim ] ( mail server ) run as stand-alone servers.
Less frequently used servers such as [ date ], [ echo ] etc etc do not
run always. A master server called [inetd] runs always. When a request
for a less frequently used server such as [date] comes, [inetd] starts
the [ date ] server. Usually [ telnetd ] is started by [inetd].
Note: [ date ], [ echo ] are two of the trivial services provided
internally by [ inetd ].
Note: [ xinetd ] is another master server with more functionality than
[ inetd ].
Examine file [ /etc/inetd.conf ] to find out if [ telnetd ] is started
by [inetd].
$ less /etc/inetd.conf
Was there any entry for [telnet] service ( Y / N )
A typical entry for [telnet] service is shown
telnet stream tcp nowait telnetd.telnetd /usr/sbin/tcpd /usr/sbin/in.telnetd
Note: The entry must be on a SINGLE line. A comment ( hash ) before a
service name, disables the service.
The [telnetd] is to be disabled using file [ /etc/inetd.conf ]
Edit file [ /etc/inetd.conf ]
# nano /etc/inetd.conf
Put a hash ( # ) mark before [telnet] service name and save the file.
Try to [telnet] to localhost.
$ telnet 127.0.0.1
This should succeed in spite of the hash before the service name. The
[inetd] process is not yet aware of the modifications made by you. If
SIGHUP signal is delivered to [ inetd ] process, its signal handler
makes arrangement to re-read its configuration file. [/etc/inetd.conf]
is the configuration file of [inetd] process.
Find out PID of [inetd] daemon process
$ ps ax | grep inetd
PID-of-inetd-->
Send SIGHUP signal to [ inetd ] daemon, to re-read [ /etc/inetd.conf ]
# kill -SIGHUP pid-of-inetd
Try to [telnet] to localhost. Now it should fail
$ telnet 127.0.0.1
Describe the steps to enable TELNET service.
Again examine the following line from [ /etc/inetd.conf ] file.
telnet stream tcp nowait telnetd.telnetd /usr/sbin/tcpd /usr/sbin/in.telnetd
The field [ /usr/sbin/tcpd ] indicates that access to [telnet] service
is controlled by [tcpd].
Access control to your host with [tcpd]:
[tcpd] program can be used to
control access to some of the services offered by your host, with two
files:
[ /etc/hosts.allow ] and [ /etc/hosts.deny ]
For access control to be effective, [tcpd] must be called first to get
the service. Check file [ /etc/inetd.conf ] to find out the services
controlled by [tcpd]. You may read manual of [tcpd(8)].
The access control software consults [/etc/hosts.allow] first and then
[/etc/hosts.deny]. The search stops at the first match. If no match is
found in either of the files, access is granted. To know about access
control rules you may read manual [hosts_access(5)].
Note: If extended access control rules are used, it is possible to use
a single access control file such as [/etc/hosts.allow].
You may read manual of hosts_options(5).
Case-1: Access is open:
The two files [/etc/hosts.allow] and
[/etc/hosts.deny] may be absent or may be present without any
rule.
OR
If the line:
ALL : ALL
is entered in [/etc/hosts.allow]. File [/etc/hosts.deny] would
not be consulted in this case, as file [ /etc/hosts.allow ] is
checked first.
Case-2: Access is mostly open and access is denied on specific cases.
File [/etc/hosts.allow] may be absent or empty of rules. File
[/etc/hosts.deny] blocks access specifically.
Example:
Edit the file [/etc/hosts.deny]
# nano /etc/hosts.deny
Add the following line in that file
in.telnetd : sumit@127.0.0.1
Save the file.
The above line deny access to user [sumit] to [telnet]
service from host 127.0.0.1 ( localhost ).
Login as [sumit] and [telnet] to localhost
sumit $ telnet 127.0.0.1
Was it successful ? ( y / N )
Login as [you] and [telnet] to localhost
you $ telnet 127.0.0.1
Was it successful ? ( Y / n )
Case-3: Access is mostly closed and access is granted on specific
cases.
Note: Paranoid System Administrators might use this scheme
The file [/etc/hosts.deny] contains a single line
ALL : ALL
This line denies access to all. As [ /etc/hosts.allow ] is
checked first, specific cases are granted access in that file.
Example:
Edit the file [/etc/hosts.deny] and add a single line
All : ALL
Save the file.
Edit [/etc/hosts.allow] and keep it blank.
Try to [telnet] to localhost as [sumit], [you],[guest]
or any other user
Were these successful ? ( y / N )
Edit [/etc/hosts.allow] and add the following line in
that file
in.telnetd : sumit@127.0.0.1
Save the file.
Try to [telnet] to localhost as [sumit]
sumit $ telnet 127.0.0.1
Was it successful ? ( Y / n )
Try to [telnet] to localhost as [you], [guest] or any
user other than [sumit]
Were these successful ? ( y / N )
Assignment-1:
Configure your host as a mostly closed system using
[tcpd] and allow:
a. [telnet] access from 172.16.2.0 network.
b. Access to all services from localhost (127.0.0.1)
Enter suitable entries in the two files
------- /etc/hosts.allow ---------
----------------------------------
--- /etc/hosts.deny ---
ALL : ALL
-----------------------
The following steps were followed to install TELNET server
1. The binary package of [telnetd] was installed
# dpkg -i telnetd_0.17-18woody2_i386.deb
2. The file [/etc/issue.net] was modified to provide some information
to the [telnet] clients.
3.
(a) Hash before [ telnet ] service line in [ /etc/inetd ] file was
removed.
(b) PID of [inetd] super-server was determined.
(c) SIGHUP signal was sent to [inetd] daemon process.
4. Mostly closed [tcpd] access control was imposed.
(a) ALL : ALL was entered in [/etc/hosts.allow] file.
(b) The file [/etc/hosts.allow] was modified as under
--------------------------------------
in.telnetd : 172.16.2.0/255.255.0.0
ALL : 127.0.0.0/255.0.0.0
--------------------------------------
IMPORTANT: At the end of this laboratory class, allow [tcpd] access to
all services on your host, from all. Enter a single line
ALL : ALL
in the file [/etc/hosts.allow].
------------------
Manuals of telnetd(8),telnet(1),issue.net(5),tcpd(8)
and hosts_access(5).
Square brackets are used to separate keywords, such as filenames,
programs names etc etc from lines of text. They have no other meaning.
A TELNET server, with minimal configuration, is to be used in this
experiment.
Create a directory named [telnet], in your home directory.
$ cd <-- puts you in your [home] directory
$ mkdir telnet
$ cd telnet
Installations are to be carried out from this directory. Binary
packages are to be installed. It is also possible to compile from
source code. Such source code may be down-loaded from Internet.
This experiment is to be carried out in Debian Linux platform. Some
Debian specific commands such as [dpkg], [dselect] etc etc have to be
used for software installation and removal. Other distributions have
similar commands of their own. Redhat Linux used [rpm] command.
The following command lists the softwares installed in your host.
$ dpkg -l
The output may be examined one screen at time
$ dpkg -l | more
If the name of the software is known partially it may be checked
$ dpkg -l | grep pyth
Find out the [telnet] related softwares installed in your host
$ dpkg -l | grep telnet
Typical output might be:
ii telnet 0.17-18woody2 The telnet client.
ii telnetd 0.17-18woody2 The telnet server.
The above lines indicate that [telnet] client and [telnet] servers are
installed in your host.
The status of the installed software can be checked.
Check the status of [telnet] client program. Output is not shown.
$ dpkg --status telnet
Check the status of [ telnetd ]. This is the server program. Output is
not shown.
$ dpkg --status telnetd
Test [telnetd] and [telnet] programs in your host
$ telnet 127.0.0.1
You may login in any user account if password is known.
As this experiment is on installation, the installed packages are to
be removed and then reinstalled.
Note: Installation and removal of software needs [root] privilege.
Remove the TELNET client program [telnet]
# dpkg -r telnet
Now the following command should fail
$ telnet 127.0.0.1
Check the [telnet] related installed packages.
$ dpkg -l | grep telnet
Output might be:
rc telnet 0.17-18woody2 The telnet client.
ii telnetd 0.17-18woody2 The telnet server.
The [ telnet ] program was removed but its configuration file was not
removed. Remove the configuration file.
# dpkg --purge telnet
Check the [telnet] related installed packages.
$ dpkg -l | grep telnet
Output might be:
ii telnetd 0.17-18woody2 The telnet server.
Check the status of [telnet] client program. Output is not shown.
$ dpkg --status telnet
Remove TELNET server program with its configuration file/files.
# dpkg --purge telnetd
Check the [telnet] related installed packages.
$ dpkg -l | grep telnet
Copy [ telnet ] and [ telnetd ] binary packages in your [ telnet ]
directory. You may use NFS or FTP for copying.
The package names might be
telnet_0.17-18woody2_i386.deb
and telnetd_0.17-18woody2_i386.deb
Note: The files are also available in first CD of a set of seven CDs.
These CDs are kept in the laboratory.
Install the TELNET client program
# dpkg -i telnet_0.17-18woody2_i386.deb
Check status of [telnet]
$ dpkg --status telnet
At present the TELNET client program is installed. Next command should
fail, as there is no TELNET server running on this host
$ telnet 127.0.0.1
However the client program can be used to access TELNET server running
on other host. Replace 192.16.5.251 with a suitable address.
$ telnet 192.16.5.251
Install the TELNET server program
# dpkg -i telnetd_0.17-18woody2_i386.deb
Check status of [telnetd]
$ dpkg --status telnetd
Find out where the executable(binary) of [telnetd] is installed
$ whereis -b in.telnetd
Location of [in.telnetd] -->
Briefly read manual of the TELNET server
$ man 8 telnetd
From the manual we find that the file [/etc/issue.net] is a text file
which contains a message or system identification to be printed before
the login prompt of a [telnet] session.
To know about the syntax of the file [ /etc/issue.net ], its manual is
consulted.
$ man 5 issue.net
A new [ issue.net ] is to be prepared, to provide the following to a
[telnet] client:
Welcome message
System node name (FQDN)
Current time and date
Name of the operating system and OS release name
Machine (hardware) type
Before modification, the original file is saved with a distinctive
extension for later identification.
$ cp /etc/issue.net ./issue.net-$USER-$( /bin/date +%H-%M )
Note the name of the saved file
$ ls -l | grep issue
Name of saved file-->
Edit [/etc/issue.net]
# nano /etc/issue.net
The file should contain the following text. Replace Sumit with your
name.
-------- /etc/issue.net --------
Welcome to Sumit's TELNET server
Terminal -----> %t
Server name --> %h
Date & time --> %d
OS -----------> %s %r
Hardware -----> %m
--------------------------------
Save the file.
Request two of your friends to [telnet] to your host. 192.169.5.146 is
assumed to be your IP address.
friend1 $ telnet 192.169.5.146
friend2 $ telnet 192.169.5.146
They should get the above information.
A server program may be kept running on a host. Such servers are
called stand-alone servers. Frequently used servers, such as [ named ]
( name server ), [ exim ] ( mail server ) run as stand-alone servers.
Less frequently used servers such as [ date ], [ echo ] etc etc do not
run always. A master server called [inetd] runs always. When a request
for a less frequently used server such as [date] comes, [inetd] starts
the [ date ] server. Usually [ telnetd ] is started by [inetd].
Note: [ date ], [ echo ] are two of the trivial services provided
internally by [ inetd ].
Note: [ xinetd ] is another master server with more functionality than
[ inetd ].
Examine file [ /etc/inetd.conf ] to find out if [ telnetd ] is started
by [inetd].
$ less /etc/inetd.conf
Was there any entry for [telnet] service ( Y / N )
A typical entry for [telnet] service is shown
telnet stream tcp nowait telnetd.telnetd /usr/sbin/tcpd /usr/sbin/in.telnetd
Note: The entry must be on a SINGLE line. A comment ( hash ) before a
service name, disables the service.
The [telnetd] is to be disabled using file [ /etc/inetd.conf ]
Edit file [ /etc/inetd.conf ]
# nano /etc/inetd.conf
Put a hash ( # ) mark before [telnet] service name and save the file.
Try to [telnet] to localhost.
$ telnet 127.0.0.1
This should succeed in spite of the hash before the service name. The
[inetd] process is not yet aware of the modifications made by you. If
SIGHUP signal is delivered to [ inetd ] process, its signal handler
makes arrangement to re-read its configuration file. [/etc/inetd.conf]
is the configuration file of [inetd] process.
Find out PID of [inetd] daemon process
$ ps ax | grep inetd
PID-of-inetd-->
Send SIGHUP signal to [ inetd ] daemon, to re-read [ /etc/inetd.conf ]
# kill -SIGHUP pid-of-inetd
Try to [telnet] to localhost. Now it should fail
$ telnet 127.0.0.1
Describe the steps to enable TELNET service.
Again examine the following line from [ /etc/inetd.conf ] file.
telnet stream tcp nowait telnetd.telnetd /usr/sbin/tcpd /usr/sbin/in.telnetd
The field [ /usr/sbin/tcpd ] indicates that access to [telnet] service
is controlled by [tcpd].
Access control to your host with [tcpd]:
[tcpd] program can be used to
control access to some of the services offered by your host, with two
files:
[ /etc/hosts.allow ] and [ /etc/hosts.deny ]
For access control to be effective, [tcpd] must be called first to get
the service. Check file [ /etc/inetd.conf ] to find out the services
controlled by [tcpd]. You may read manual of [tcpd(8)].
The access control software consults [/etc/hosts.allow] first and then
[/etc/hosts.deny]. The search stops at the first match. If no match is
found in either of the files, access is granted. To know about access
control rules you may read manual [hosts_access(5)].
Note: If extended access control rules are used, it is possible to use
a single access control file such as [/etc/hosts.allow].
You may read manual of hosts_options(5).
Case-1: Access is open:
The two files [/etc/hosts.allow] and
[/etc/hosts.deny] may be absent or may be present without any
rule.
OR
If the line:
ALL : ALL
is entered in [/etc/hosts.allow]. File [/etc/hosts.deny] would
not be consulted in this case, as file [ /etc/hosts.allow ] is
checked first.
Case-2: Access is mostly open and access is denied on specific cases.
File [/etc/hosts.allow] may be absent or empty of rules. File
[/etc/hosts.deny] blocks access specifically.
Example:
Edit the file [/etc/hosts.deny]
# nano /etc/hosts.deny
Add the following line in that file
in.telnetd : sumit@127.0.0.1
Save the file.
The above line deny access to user [sumit] to [telnet]
service from host 127.0.0.1 ( localhost ).
Login as [sumit] and [telnet] to localhost
sumit $ telnet 127.0.0.1
Was it successful ? ( y / N )
Login as [you] and [telnet] to localhost
you $ telnet 127.0.0.1
Was it successful ? ( Y / n )
Case-3: Access is mostly closed and access is granted on specific
cases.
Note: Paranoid System Administrators might use this scheme
The file [/etc/hosts.deny] contains a single line
ALL : ALL
This line denies access to all. As [ /etc/hosts.allow ] is
checked first, specific cases are granted access in that file.
Example:
Edit the file [/etc/hosts.deny] and add a single line
All : ALL
Save the file.
Edit [/etc/hosts.allow] and keep it blank.
Try to [telnet] to localhost as [sumit], [you],[guest]
or any other user
Were these successful ? ( y / N )
Edit [/etc/hosts.allow] and add the following line in
that file
in.telnetd : sumit@127.0.0.1
Save the file.
Try to [telnet] to localhost as [sumit]
sumit $ telnet 127.0.0.1
Was it successful ? ( Y / n )
Try to [telnet] to localhost as [you], [guest] or any
user other than [sumit]
Were these successful ? ( y / N )
Assignment-1:
Configure your host as a mostly closed system using
[tcpd] and allow:
a. [telnet] access from 172.16.2.0 network.
b. Access to all services from localhost (127.0.0.1)
Enter suitable entries in the two files
------- /etc/hosts.allow ---------
----------------------------------
--- /etc/hosts.deny ---
ALL : ALL
-----------------------
The following steps were followed to install TELNET server
1. The binary package of [telnetd] was installed
# dpkg -i telnetd_0.17-18woody2_i386.deb
2. The file [/etc/issue.net] was modified to provide some information
to the [telnet] clients.
3.
(a) Hash before [ telnet ] service line in [ /etc/inetd ] file was
removed.
(b) PID of [inetd] super-server was determined.
(c) SIGHUP signal was sent to [inetd] daemon process.
4. Mostly closed [tcpd] access control was imposed.
(a) ALL : ALL was entered in [/etc/hosts.allow] file.
(b) The file [/etc/hosts.allow] was modified as under
--------------------------------------
in.telnetd : 172.16.2.0/255.255.0.0
ALL : 127.0.0.0/255.0.0.0
--------------------------------------
IMPORTANT: At the end of this laboratory class, allow [tcpd] access to
all services on your host, from all. Enter a single line
ALL : ALL
in the file [/etc/hosts.allow].
------------------
Socket 2
Documents to read:
1. Internetworking with TCP/IP Volume-III
by
Douglas E. Comer & David L. Stevens
2. Manuals socket(2), ip(7),
tcp(7) and fork(2)
Square brackets are used to separate keywords, such as filenames,
programs names etc etc from lines of text. They have no other meaning.
Create directory [socket2] in your home directory.
$ mkdir $HOME/socket2
Change into [socket2] directory
$ cd $HOME/socket2
Bring the file [ socket2-681.txt ] in this directory using NFS or FTP.
Creation of a new process:
A new process can be created with [fork()]
system call. Read manual of fork.
$ man 2 fork
After the [fork()] call, the newly created process is called [ child ]
and the main program is called [parent] process. The codes that follow
the [fork()] call is executed by the [ parent ] and the [ child ]. Who
executes first is not predictable.
Save the following code as [f1.c].
--------------------------------------------------
// file-name f1.c
// example of fork()
#include
#include
int main( void)
{
pid_t x;
// a new process is created
x = fork();
// following lines are executed by two processes
write( STDOUT_FILENO,"My name is Sumit\n", 17 );
return 0;
}
--------------------------------------------------
Compile and execute the program.
$ gcc -Wall ./f1.c -o ./one
$ ./one
Was the line "My name is Sumit" printed twice ? ( Y / n )
The two processes can be made to execute separate blocks of code. The
[ fork() ] call returns two PID values. The variable [ x ] gets two
values. The [child] gets x=0 and the parent gets x=some-other-integer.
Zero is not the PID of the [ child ] process, but this can be used to
confine the [child] process to a given block of code. The rest of the
codes are executed by the parent process.
Save the following as [f2.c]
----------------------------------------------------
// file-name f2.c
// example of fork()
#include
#include
#include
int main( void)
{
pid_t x;
x = fork();
// two values of x are printed.
printf("x = %u\n", x );
// both the processes sleep for a second. This is
// used only to impart some clarity in the output.
sleep(1);
if( x == 0 ) // child process
{
printf("x = %u; I am child\n", x );
exit(0);
} // end of child's block
// rest is parent process
printf("x = %u; I am parent\n", x );
return 0;
}
----------------------------------------------------
Compile and run the program.
$ gcc -Wall ./f2.c -o ./two
$ ./two
Did the child execute it's block of code ? ( Y / n )
Run the program a number of times.
Was the parent running first ? ( y / n / unpredictable )
In a concurrent server using process, a new [child] process is created
for each client's request. While a client's request is being processed
by the [ child ] process, the parent waits for the next request from
another client. If the [child] exits but the parent continues and does
not read the exit status of the child; [ zombie ] process is created.
The next program creates ten [zombie] processes.
Save the following program as [f3.c]
---------------------------------
// file-name f3.c
// creation of zombie process
#include
#include
#include
#include
int main( void)
{
pid_t x;
int n = 10;
while( n > 0 )
{
x = fork();
if( x == 0 ) // child process
{
exit(0);
} // end of child's block
n--;
//wait(NULL);
}
while(1) { sleep(1); }
}
---------------------------------
Compile and run the executable.
$ gcc -Wall ./f3.c -o ./three
$ ./three
In another terminal check processes
$ ps ax
Were zombies created ? ( Y / n )
When the parent exits, the operating system removes the zombies.
Terminate [three] with CTRL-c.
Were zombies removed ? ( Y / n )
The [zombie] processes, if not reaped (removed), use system resources.
If the [parent] reads the exit status of a [child], the [ zombie ] is
removed. Parent can use [ wait() ] system call to read the exit status
of a child. You may read the manual of [wait] and [waitpid] calls.
$ man 2 wait
Uncomment the line
//wait(NULL);
in [f3.c], compile and run the executable.
$ gcc -Wall ./f3.c -o ./three
$ ./three
In another terminal check the processes
$ ps ax
Was any zombie created ? ( y / N )
Terminate [three] with CTRL-c.
Whenever a [ child ] exits or stops, the operating system delivers a
SIGCHLD signal to the [parent] process. In [f4.c], the parent installs
a signal handler for SIGCHLD. The [parent] reads the exit status of a
child within the signal handler, whenever a [ child ] stops or exits.
The SIGCHLD signal might interrupt whatever the parent was executing.
The program [f4.c] is a concurrent TCP ECHO server. This program uses
a SIGCHLD handler to reap zombies.
------------------------------------------------------------
// file-name f4.c
// TCP ECHO server( concurrent - using process )
// Using SIGCHLD handler to reap zombie
// usage: program-name
#include
#include
#include
#include
#include
#include
#include
#include
#define LOCAL_PORT 65432
// signal handler prototype
void reap_zombie( int signum );
// a global variable
jmp_buf yy;
int main ( void )
{
int serv_sd; // socket descriptor
int temp_sd; // socket descriptor
int n;
struct sockaddr_in serv_addr; // IPv4 address
struct sigaction act; // signal action
sigset_t ss; // signal set
pid_t pid;
// members of [serv_addr] are initialised
serv_addr.sin_family = AF_INET;
serv_addr.sin_port = htons( LOCAL_PORT );
serv_addr.sin_addr.s_addr = htonl( INADDR_ANY );
// TCP ( IPv4 stream ) socket is created
serv_sd = socket( PF_INET, SOCK_STREAM, IPPROTO_TCP );
if( serv_sd == -1 ) { perror("socket-call"); exit(1); }
// TCP socket is bound to a local address
n = bind( serv_sd,
( struct sockaddr *) &serv_addr,
sizeof(serv_addr) );
if( n == -1 ) { perror("bind-call"); exit(1); }
// TCP socket is put in listening state
n = listen( serv_sd, 5 );
if( n == -1 ) { perror("listen-call"); exit(1); }
// main installs signal handler for SIGCHLD
act.sa_handler = reap_zombie;
act.sa_mask = ss;
act.sa_flags = 0;
n = sigaction( SIGCHLD, &act, NULL );
if ( n == -1 ) { perror("sigaction"); exit(1); }
// server accepts client's request in an endless loop
while( 1 )
{
printf( "accepting request on TCP port %u\n",
LOCAL_PORT );
// If [accept()] call is interrupted by SIGCHLD, return
// here from signal handler.
n = sigsetjmp(yy,1); // second argument is non-zero
if( n == 0 ) printf("normal flow\n");
if( n == 66 ) printf("returning from interrupt\n");
temp_sd = accept( serv_sd, NULL, 0 );
if( temp_sd == -1 ) perror("accept-call");
pid = fork();
if( pid == -1 ) perror("fork");
if( pid == 0 ) // child process handles client's request
{
#define BUFFERSIZE 1024
char buffer[BUFFERSIZE];
ssize_t i, j ;
// clear buffer
memset( buffer, '\0', BUFFERSIZE );
// read clients request string in the buffer
i = read( temp_sd, buffer, BUFFERSIZE );
printf("child: %u bytes received from client\n", i );
// write the contents of the buffer in the [temp_sd]
j = write( temp_sd, buffer, i );
if( j == -1 ) { perror("write-call"); }
shutdown( temp_sd, SHUT_RDWR );
close( temp_sd );
exit(0);
} // end of child's block
// rest is parent's code
close( temp_sd );
} //end of endless loop
return 0;
} //end of main
// signal handler
void reap_zombie( int signum )
{
pid_t pid;
printf("reap-zombie: received signal %u\n", signum );
pid = waitpid( 0, NULL, WNOHANG );
if( pid == -1 ) perror("waitpid");
siglongjmp(yy,66);
}
------------------------------------------------------------
Compile and run the server.
$ gcc -Wall ./f4.c -o ./four
$ ./four
Request your friends to use your ECHO server.
friend $ tcp-echo-client your-ip-address your-port-number
From another terminal use your ECHO server repeatedly.
$ tcp-echo-client 127.0.0.1 65432
Check processes
$ ps ax
Was there any zombie process ? ( y / N )
If reaping of [ zombie ] is not done with SIGCHLD handler, the above
program can be simplified. In [f5.c] SIGCHLD handler is not used.
-------------------------------------------------------------------
// file-name f5.c
// TCP ECHO server(concurrent - using fork) without SIGCHLD handler
// usage: program-name
#include
#include
#include
#include
#include
#include
#define LOCAL_PORT 65432
int main ( void )
{
int serv_sd; // socket descriptor
int temp_sd; // socket descriptor
int n;
struct sockaddr_in serv_addr; // IPv4 address
pid_t pid,x;
// members of [serv_addr] are initialised
serv_addr.sin_family = AF_INET;
serv_addr.sin_port = htons( LOCAL_PORT );
serv_addr.sin_addr.s_addr = htonl( INADDR_ANY );
// TCP ( IPv4 stream ) socket is created
serv_sd = socket( PF_INET, SOCK_STREAM, IPPROTO_TCP );
if( serv_sd == -1 ) { perror("socket-call"); exit(1); }
// TCP socket is bound to a local address
n = bind( serv_sd,
( struct sockaddr *) &serv_addr,
sizeof(serv_addr) );
if( n == -1 ) { perror("bind-call"); exit(1); }
// TCP socket is put in listening state
n = listen( serv_sd, 5 );
if( n == -1 ) { perror("listen-call"); exit(1); }
// server accepts client's request in an endless loop
while( 1 )
{
printf( "server: accepting request on TCP port %u\n",
LOCAL_PORT );
temp_sd = accept( serv_sd, NULL, 0 );
if( temp_sd == -1 ) perror("accept-call");
// create a process
pid = fork();
if( pid == -1 ) { perror("fork"); exit(1); }
if( pid == 0 ) // child process handles client's request
{
#define BUFFERSIZE 1024
char buffer[BUFFERSIZE];
ssize_t i, j ;
// clear buffer
memset( buffer, '\0', BUFFERSIZE );
// read clients request string in the buffer
i = read( temp_sd, buffer, BUFFERSIZE );
printf("server: %u bytes received from client\n", i );
// write the contents of the buffer in the [temp_sd]
j = write( temp_sd, buffer, i );
if( j == -1 ) { perror("write-call"); }
shutdown( temp_sd, SHUT_RDWR );
close( temp_sd );
exit(0);
} // end of child's block
// rest is parent's code
close( temp_sd );
x = waitpid( 0, NULL, WNOHANG );
if( x == -1 ) perror("waitpid");
} //end of endless loop
return 0;
} //end of main
-------------------------------------------------------------------
Compile and run the server
$ gcc -Wall ./f5.c -o ./ser-con-p
$ ./ser-con-p
Use the ECHO server repeatedly
$ tcp-echo-client 127.0.0.1 65432
Was some zombie remained in system ? ( Y / n )
In the following program [f6.c], main program creates a [ thread ] to
process a client's request, after a successful [accept()] system call.
When a [ thread ] is created, it starts to execute it's start routine,
with the supplied argument. Main program creates the [thread] with the
newly created socket, as the argument.
----------------------------------------------------------------------
// file-name f6.c
// TCP echo server (concurrent - using threads)
// usage: program-name
#include
#include
#include
#include
#include
#define PORT 65432
void func( int arg );
int main(void)
{
int ser_sd,tempsd;
int n;
struct sockaddr_in ser_addr;
pthread_t x; // a thread item
ser_addr.sin_family = AF_INET;
ser_addr.sin_port = htons( PORT );
ser_addr.sin_addr.s_addr = htonl( INADDR_ANY );
ser_sd = socket( AF_INET, SOCK_STREAM, IPPROTO_TCP );
if( ser_sd == -1 ) { perror("socket"); exit(1); }
n = bind( ser_sd,(struct sockaddr *) &ser_addr,
sizeof(ser_addr) );
if( n == -1) { perror("bind"); exit(1); }
n = listen( ser_sd, 5 );
if( n == -1 ) { perror("listen"); exit(1); }
while ( 1 )
{
printf("server is ready on TCP port %u \n", PORT );
// wait for a client's request
tempsd = accept( ser_sd, NULL, 0 );
if( tempsd == -1 ) perror("accept");
else
{
printf("creating a thread to process client's request\n");
n = pthread_create( &x, NULL,( void *) func, (void *) tempsd );
if( n != 0 ) perror("pthread_create");
}
} // endless loop
return 0;
}
// client's request is processes by this thread
void func( int arg )
{
#define BUFFERSIZE 1024
char buffer[BUFFERSIZE];
ssize_t i,j;
int n;
memset(buffer, '\0', BUFFERSIZE);
i = read( arg, buffer, BUFFERSIZE);
if( i == -1 ) { perror("read"); exit(1); }
printf("thread: read %u bytes from server\n", i );
// write [i] bytes to client
j = write( arg, buffer, i );
if(j == -1 ) { perror("write"); exit(1); }
n = shutdown( arg, SHUT_RDWR );
if( n == -1 ) { perror("shutdown"); }
close(arg);
pthread_exit(NULL);
}
----------------------------------------------------------------------
Compile and run the executable.
$ gcc -Wall -D_RENTRANT -lpthread ./f6.c -o ./ser-con-t
$ ./ser-con-t
Test the ECHO server from localhost and from other hosts.
Did the ECHO server process multiple client requests ? ( Y / n )
----------------------------
Optional assignment-1:
Trace system calls and signals when the program
[four] executes and client connects to it.
$ strace ./four
Optional assignment-2:
Capture packets generated by client and server.
Start ECHO server
$ ./ser-con-t
In another terminal, capture TCP packets, to and from your host. Save
the captured packets in a file [kk] in the current directory.
# tcpdump -i eth0 host your-ip-address and tcp -w ./kk
The data in file [ kk ] is not text. Convert the captured data into
text and save it in file [jj]. in the current directory.
# tethereal -V -r ./kk > ./jj
Examine the text file.
# less ./jj
-------------------
1. Internetworking with TCP/IP Volume-III
by
Douglas E. Comer & David L. Stevens
2. Manuals socket(2), ip(7),
tcp(7) and fork(2)
Square brackets are used to separate keywords, such as filenames,
programs names etc etc from lines of text. They have no other meaning.
Create directory [socket2] in your home directory.
$ mkdir $HOME/socket2
Change into [socket2] directory
$ cd $HOME/socket2
Bring the file [ socket2-681.txt ] in this directory using NFS or FTP.
Creation of a new process:
A new process can be created with [fork()]
system call. Read manual of fork.
$ man 2 fork
After the [fork()] call, the newly created process is called [ child ]
and the main program is called [parent] process. The codes that follow
the [fork()] call is executed by the [ parent ] and the [ child ]. Who
executes first is not predictable.
Save the following code as [f1.c].
--------------------------------------------------
// file-name f1.c
// example of fork()
#include
#include
int main( void)
{
pid_t x;
// a new process is created
x = fork();
// following lines are executed by two processes
write( STDOUT_FILENO,"My name is Sumit\n", 17 );
return 0;
}
--------------------------------------------------
Compile and execute the program.
$ gcc -Wall ./f1.c -o ./one
$ ./one
Was the line "My name is Sumit" printed twice ? ( Y / n )
The two processes can be made to execute separate blocks of code. The
[ fork() ] call returns two PID values. The variable [ x ] gets two
values. The [child] gets x=0 and the parent gets x=some-other-integer.
Zero is not the PID of the [ child ] process, but this can be used to
confine the [child] process to a given block of code. The rest of the
codes are executed by the parent process.
Save the following as [f2.c]
----------------------------------------------------
// file-name f2.c
// example of fork()
#include
#include
#include
int main( void)
{
pid_t x;
x = fork();
// two values of x are printed.
printf("x = %u\n", x );
// both the processes sleep for a second. This is
// used only to impart some clarity in the output.
sleep(1);
if( x == 0 ) // child process
{
printf("x = %u; I am child\n", x );
exit(0);
} // end of child's block
// rest is parent process
printf("x = %u; I am parent\n", x );
return 0;
}
----------------------------------------------------
Compile and run the program.
$ gcc -Wall ./f2.c -o ./two
$ ./two
Did the child execute it's block of code ? ( Y / n )
Run the program a number of times.
Was the parent running first ? ( y / n / unpredictable )
In a concurrent server using process, a new [child] process is created
for each client's request. While a client's request is being processed
by the [ child ] process, the parent waits for the next request from
another client. If the [child] exits but the parent continues and does
not read the exit status of the child; [ zombie ] process is created.
The next program creates ten [zombie] processes.
Save the following program as [f3.c]
---------------------------------
// file-name f3.c
// creation of zombie process
#include
#include
#include
#include
int main( void)
{
pid_t x;
int n = 10;
while( n > 0 )
{
x = fork();
if( x == 0 ) // child process
{
exit(0);
} // end of child's block
n--;
//wait(NULL);
}
while(1) { sleep(1); }
}
---------------------------------
Compile and run the executable.
$ gcc -Wall ./f3.c -o ./three
$ ./three
In another terminal check processes
$ ps ax
Were zombies created ? ( Y / n )
When the parent exits, the operating system removes the zombies.
Terminate [three] with CTRL-c.
Were zombies removed ? ( Y / n )
The [zombie] processes, if not reaped (removed), use system resources.
If the [parent] reads the exit status of a [child], the [ zombie ] is
removed. Parent can use [ wait() ] system call to read the exit status
of a child. You may read the manual of [wait] and [waitpid] calls.
$ man 2 wait
Uncomment the line
//wait(NULL);
in [f3.c], compile and run the executable.
$ gcc -Wall ./f3.c -o ./three
$ ./three
In another terminal check the processes
$ ps ax
Was any zombie created ? ( y / N )
Terminate [three] with CTRL-c.
Whenever a [ child ] exits or stops, the operating system delivers a
SIGCHLD signal to the [parent] process. In [f4.c], the parent installs
a signal handler for SIGCHLD. The [parent] reads the exit status of a
child within the signal handler, whenever a [ child ] stops or exits.
The SIGCHLD signal might interrupt whatever the parent was executing.
The program [f4.c] is a concurrent TCP ECHO server. This program uses
a SIGCHLD handler to reap zombies.
------------------------------------------------------------
// file-name f4.c
// TCP ECHO server( concurrent - using process )
// Using SIGCHLD handler to reap zombie
// usage: program-name
#include
#include
#include
#include
#include
#include
#include
#include
#define LOCAL_PORT 65432
// signal handler prototype
void reap_zombie( int signum );
// a global variable
jmp_buf yy;
int main ( void )
{
int serv_sd; // socket descriptor
int temp_sd; // socket descriptor
int n;
struct sockaddr_in serv_addr; // IPv4 address
struct sigaction act; // signal action
sigset_t ss; // signal set
pid_t pid;
// members of [serv_addr] are initialised
serv_addr.sin_family = AF_INET;
serv_addr.sin_port = htons( LOCAL_PORT );
serv_addr.sin_addr.s_addr = htonl( INADDR_ANY );
// TCP ( IPv4 stream ) socket is created
serv_sd = socket( PF_INET, SOCK_STREAM, IPPROTO_TCP );
if( serv_sd == -1 ) { perror("socket-call"); exit(1); }
// TCP socket is bound to a local address
n = bind( serv_sd,
( struct sockaddr *) &serv_addr,
sizeof(serv_addr) );
if( n == -1 ) { perror("bind-call"); exit(1); }
// TCP socket is put in listening state
n = listen( serv_sd, 5 );
if( n == -1 ) { perror("listen-call"); exit(1); }
// main installs signal handler for SIGCHLD
act.sa_handler = reap_zombie;
act.sa_mask = ss;
act.sa_flags = 0;
n = sigaction( SIGCHLD, &act, NULL );
if ( n == -1 ) { perror("sigaction"); exit(1); }
// server accepts client's request in an endless loop
while( 1 )
{
printf( "accepting request on TCP port %u\n",
LOCAL_PORT );
// If [accept()] call is interrupted by SIGCHLD, return
// here from signal handler.
n = sigsetjmp(yy,1); // second argument is non-zero
if( n == 0 ) printf("normal flow\n");
if( n == 66 ) printf("returning from interrupt\n");
temp_sd = accept( serv_sd, NULL, 0 );
if( temp_sd == -1 ) perror("accept-call");
pid = fork();
if( pid == -1 ) perror("fork");
if( pid == 0 ) // child process handles client's request
{
#define BUFFERSIZE 1024
char buffer[BUFFERSIZE];
ssize_t i, j ;
// clear buffer
memset( buffer, '\0', BUFFERSIZE );
// read clients request string in the buffer
i = read( temp_sd, buffer, BUFFERSIZE );
printf("child: %u bytes received from client\n", i );
// write the contents of the buffer in the [temp_sd]
j = write( temp_sd, buffer, i );
if( j == -1 ) { perror("write-call"); }
shutdown( temp_sd, SHUT_RDWR );
close( temp_sd );
exit(0);
} // end of child's block
// rest is parent's code
close( temp_sd );
} //end of endless loop
return 0;
} //end of main
// signal handler
void reap_zombie( int signum )
{
pid_t pid;
printf("reap-zombie: received signal %u\n", signum );
pid = waitpid( 0, NULL, WNOHANG );
if( pid == -1 ) perror("waitpid");
siglongjmp(yy,66);
}
------------------------------------------------------------
Compile and run the server.
$ gcc -Wall ./f4.c -o ./four
$ ./four
Request your friends to use your ECHO server.
friend $ tcp-echo-client your-ip-address your-port-number
From another terminal use your ECHO server repeatedly.
$ tcp-echo-client 127.0.0.1 65432
Check processes
$ ps ax
Was there any zombie process ? ( y / N )
If reaping of [ zombie ] is not done with SIGCHLD handler, the above
program can be simplified. In [f5.c] SIGCHLD handler is not used.
-------------------------------------------------------------------
// file-name f5.c
// TCP ECHO server(concurrent - using fork) without SIGCHLD handler
// usage: program-name
#include
#include
#include
#include
#include
#include
#define LOCAL_PORT 65432
int main ( void )
{
int serv_sd; // socket descriptor
int temp_sd; // socket descriptor
int n;
struct sockaddr_in serv_addr; // IPv4 address
pid_t pid,x;
// members of [serv_addr] are initialised
serv_addr.sin_family = AF_INET;
serv_addr.sin_port = htons( LOCAL_PORT );
serv_addr.sin_addr.s_addr = htonl( INADDR_ANY );
// TCP ( IPv4 stream ) socket is created
serv_sd = socket( PF_INET, SOCK_STREAM, IPPROTO_TCP );
if( serv_sd == -1 ) { perror("socket-call"); exit(1); }
// TCP socket is bound to a local address
n = bind( serv_sd,
( struct sockaddr *) &serv_addr,
sizeof(serv_addr) );
if( n == -1 ) { perror("bind-call"); exit(1); }
// TCP socket is put in listening state
n = listen( serv_sd, 5 );
if( n == -1 ) { perror("listen-call"); exit(1); }
// server accepts client's request in an endless loop
while( 1 )
{
printf( "server: accepting request on TCP port %u\n",
LOCAL_PORT );
temp_sd = accept( serv_sd, NULL, 0 );
if( temp_sd == -1 ) perror("accept-call");
// create a process
pid = fork();
if( pid == -1 ) { perror("fork"); exit(1); }
if( pid == 0 ) // child process handles client's request
{
#define BUFFERSIZE 1024
char buffer[BUFFERSIZE];
ssize_t i, j ;
// clear buffer
memset( buffer, '\0', BUFFERSIZE );
// read clients request string in the buffer
i = read( temp_sd, buffer, BUFFERSIZE );
printf("server: %u bytes received from client\n", i );
// write the contents of the buffer in the [temp_sd]
j = write( temp_sd, buffer, i );
if( j == -1 ) { perror("write-call"); }
shutdown( temp_sd, SHUT_RDWR );
close( temp_sd );
exit(0);
} // end of child's block
// rest is parent's code
close( temp_sd );
x = waitpid( 0, NULL, WNOHANG );
if( x == -1 ) perror("waitpid");
} //end of endless loop
return 0;
} //end of main
-------------------------------------------------------------------
Compile and run the server
$ gcc -Wall ./f5.c -o ./ser-con-p
$ ./ser-con-p
Use the ECHO server repeatedly
$ tcp-echo-client 127.0.0.1 65432
Was some zombie remained in system ? ( Y / n )
In the following program [f6.c], main program creates a [ thread ] to
process a client's request, after a successful [accept()] system call.
When a [ thread ] is created, it starts to execute it's start routine,
with the supplied argument. Main program creates the [thread] with the
newly created socket, as the argument.
----------------------------------------------------------------------
// file-name f6.c
// TCP echo server (concurrent - using threads)
// usage: program-name
#include
#include
#include
#include
#include
#define PORT 65432
void func( int arg );
int main(void)
{
int ser_sd,tempsd;
int n;
struct sockaddr_in ser_addr;
pthread_t x; // a thread item
ser_addr.sin_family = AF_INET;
ser_addr.sin_port = htons( PORT );
ser_addr.sin_addr.s_addr = htonl( INADDR_ANY );
ser_sd = socket( AF_INET, SOCK_STREAM, IPPROTO_TCP );
if( ser_sd == -1 ) { perror("socket"); exit(1); }
n = bind( ser_sd,(struct sockaddr *) &ser_addr,
sizeof(ser_addr) );
if( n == -1) { perror("bind"); exit(1); }
n = listen( ser_sd, 5 );
if( n == -1 ) { perror("listen"); exit(1); }
while ( 1 )
{
printf("server is ready on TCP port %u \n", PORT );
// wait for a client's request
tempsd = accept( ser_sd, NULL, 0 );
if( tempsd == -1 ) perror("accept");
else
{
printf("creating a thread to process client's request\n");
n = pthread_create( &x, NULL,( void *) func, (void *) tempsd );
if( n != 0 ) perror("pthread_create");
}
} // endless loop
return 0;
}
// client's request is processes by this thread
void func( int arg )
{
#define BUFFERSIZE 1024
char buffer[BUFFERSIZE];
ssize_t i,j;
int n;
memset(buffer, '\0', BUFFERSIZE);
i = read( arg, buffer, BUFFERSIZE);
if( i == -1 ) { perror("read"); exit(1); }
printf("thread: read %u bytes from server\n", i );
// write [i] bytes to client
j = write( arg, buffer, i );
if(j == -1 ) { perror("write"); exit(1); }
n = shutdown( arg, SHUT_RDWR );
if( n == -1 ) { perror("shutdown"); }
close(arg);
pthread_exit(NULL);
}
----------------------------------------------------------------------
Compile and run the executable.
$ gcc -Wall -D_RENTRANT -lpthread ./f6.c -o ./ser-con-t
$ ./ser-con-t
Test the ECHO server from localhost and from other hosts.
Did the ECHO server process multiple client requests ? ( Y / n )
----------------------------
Optional assignment-1:
Trace system calls and signals when the program
[four] executes and client connects to it.
$ strace ./four
Optional assignment-2:
Capture packets generated by client and server.
Start ECHO server
$ ./ser-con-t
In another terminal, capture TCP packets, to and from your host. Save
the captured packets in a file [kk] in the current directory.
# tcpdump -i eth0 host your-ip-address and tcp -w ./kk
The data in file [ kk ] is not text. Convert the captured data into
text and save it in file [jj]. in the current directory.
# tethereal -V -r ./kk > ./jj
Examine the text file.
# less ./jj
-------------------
Socket1
Documents to read:
1. UNIX Network Programming
By W. Richard Stevens
Chapter-6, on Berkeley Sockets
2. Manuals socket(2), ip(7),
tcp(7) and udp(7)
Square brackets are used to separate keywords, such as filenames,
programs names etc etc from lines of text. They have no other meaning.
Go to your home directory
$ cd
Verify the current directory
$ pwd
Create directory [socket1] in your home directory.
$ mkdir socket1
Change into [socket1] directory
$ cd socket1
Bring the file [socket1.txt] in this directory using NFS
$ mount /ftp-server
$ cd /ftp-server
.
.
You may also use [ftp] to bring the file.
SOCKET:
A socket is an endpoint for communication. Sockets are the
primary means of communicating with other hosts; telnet, rlogin, ftp,
talk and the other familiar network programs use sockets.
Different types of [socket]s can be created by [socket()] system call.
Consult the manual of this system call from section 2 of manual.
$ man 2 socket
[socket()] call takes three arguments. An unsigned integer is returned
when the call is successful. This integer is the file descriptor of
the socket. As with regular file descriptors, writing in the socket,
reading from the socket, closing the socket etc etc can be done, using
this descriptor.
Type of the created socket depends on the arguments used. In this
laboratory, we are going to use sockets suitable for network communic-
ation using IPv4 Internet protocols. From the above manual we find
that we have to consult the manual of [ip] from section 7 of the UNIX
manual, for the arguments to be used for creating IPv4 sockets.
$ man 7 ip
A TCP socket ( IPv4 stream socket ) can be created with...
tcp_socket = socket(PF_INET, SOCK_STREAM, IPPROTO_TCP);
An UDP socket ( IPv4 datagram socket ) can be created with...
udp_socket = socket(PF_INET, SOCK_DGRAM, IPPROTO_UDP);
Zero may be used to replace IPPROTO_TCP and IPPROTO_UDP. Zero is IP
pseudo protocol number.
We are not going to use [raw_socket] in this experiment.
Save the following program as [f1.c].
---------------------------------------------------------------------
// file-name f1.c
// One TCP and one UDP socket are created
// usage: program-name
#include
#include
#include
#include
int main ( void )
{
int sd1, sd2 ;
// sd1 and sd2 would be used as socket-file-descriptors
// Values of two symbolic constants are printed
printf("IPPROTO_TCP = %u \n", IPPROTO_TCP );
printf("IPPROTO_UDP = %u \n", IPPROTO_UDP );
// process number of this program
printf("PID = %u \n", getpid() );
// TCP ( IPv4 stream ) socket is created
sd1 = socket( PF_INET, SOCK_STREAM, IPPROTO_TCP );
// Numerical value of the socket descriptor is printed
printf("value of TCP socket descriptor = %u \n", sd1 );
// UDP ( IPv4 datagram ) socket is created
sd2 = socket( PF_INET, SOCK_DGRAM, IPPROTO_UDP );
// Numerical value of the socket descriptor is printed
printf("value of UDP socket descriptor = %u \n", sd2 );
// If the program exits, operating system closes (removes) the
// descriptors. The following endless loop is used for checking
// the creation of the two sockets.
while( 1 ) { sleep(1); }
return 0;
} //end of main
---------------------------------------------------------------------
Assignment-1:
Compile the program
$ gcc -Wall ./f1.c -o ./one
Run the executable program, do not terminate the program and record
the following from the output of the program:
$ ./one
IPPROTO_TCP = ___
IPPROTO_UDP = ___
PID = ________
value of TCP socket descriptor = ___
value of UDP socket descriptor = ___
As the program runs in this terminal, this terminal is unusable now.
Note: The program can be started in background also.
$ ./one &
If the program runs in the background, this terminal becomes
usable.
Verify the PID of your program
$ ps ax | grep one
In another terminal, examine the file [/etc/protocols] and record the
following
$ less /etc/protocols
protocols-name protocols-number
IP ------------> ___
TCP -----------> ___
UDP -----------> ___
Check the creation of the sockets with the following command
$ ls -l /proc/value-of-PID/fd
Were the two sockets created ? ( Y / n )
Terminate the running program [one] with CTRL-C.
End of Assignment-1.
5-tuple association for network communication may be stated as:
(protocol,local-address,local-process,foreign-address,foreign-process)
Assignment-2.
In this assignment, a 5-tuple association for network
communication is to be verified. The [echo] server process using TCP,
running in your friend's host, are the [ foreign-address ], [ foreign-
process ] and [ protocol ].
Examine file [/etc/services] and record:
$ less /etc/services
[echo] server, using TCP protocol, runs on port number ____ .
[foreign-process] is NOT the PID of the [echo] server process, but it
is the port number, the [echo] server process associates with. If the
[ echo ] server process is restarted, its PID would change but its
association with port number - 7 would be unaltered. This port number
is well-known to the [ client/clients ].
At present we do not have any TCP [echo] client program. Later in this
experiment we are going to write a TCP [echo] client program.
[telnet] is a [client] program used to connect to the [telnetd] server
program. [ telnet ] connects to port-23 of the specified host, if port
number is not specified. If port number is specified, [ telnet ]
connects to that port.
The two commands should give the same result
$ telnet 192.168.5.145
or
$ telnet 172.16.2.145 23
If port number is specified as 7, [ telnet ] program may be used to
communicate with the [echo] server. Replace 172.16.2.145 with the IP
address of your friend's host.
$ telnet 172.16.2.145 7
Enter any string. It should be echoed on your terminal.
[ telnet ] program used in your host, is the [ local-process ]. PID of
[telnet] process is NOT the [[local-process], it is the port number it
is associated with. This port number ( in the range 1024 - 65535 ) is
alloted to that instance of [telnet] process, by the operating system
and it is guaranteed to be free, no other process using TCP protocol
was using it. The port assigned to the [ client ] process is called
ephemeral ( short lived ) port. The PID and the ephemeral port might
change with each invocation of the [client] process.
----------- ----------------
| | | |
| Your host |_____________________| Friend's Host |
| client | | echo server(7) |
| | | |
----------- ----------------
Connect to the [ echo ] server of your friend but do not enter any
string. In this condition a TCP connection is established.
$ telnet 172.16.2.145 7
In another terminal, login in your account ( or login as [root] ) and
use the following command.
$ ps ax
PID of the [telnet] process -->
Use the following command...
$ netstat -atnp
You may read manual of this command [ $ man 8 netstat ].
The meaning of the options are reproduced from the manual:
a all
t TCP
n numeric output
p show PID and program name
If the output is more than one screenful, you can store the result in
a file and examine the file with a pager, such as [less].
$ netstat -atnp >tmp 2>&1
$ less ./tmp
Fill up the following table.
proto loc-add:loc-port for-add:for-port state PID/prog-name
tcp :7 ESTABLISHED
The above is the 5-tuple association.
End of Assignment-2.
The system calls used by the [server] and the [client] for connection
oriented protocol are shown below ( From "UNIX Network Programming" by
W.Richard Stevens ). TCP is a connection oriented protocol.
SERVER
socket()
|
bind()
|
listen()
|
accept() CLIENT
|
Blocks until connection socket()
from client |
| connection establishment |
|<-----------------------------------------> connect()
| |
read() <------------------------------------- write()
| data (request from client) |
| |
process client's request |
| |
write() --------------------------------------> read()
data (reply from server)
A newly created socket is not useful for communication. An address is
to be assigned to it.
The format of a IPv4 address is reproduces from manual [ip(7)].
struct sockaddr_in
{
sa_family_t sin_family; // address family: AF_INET
u_int16_t sin_port; // port in network byte
struct in_addr sin_addr; // internet address
};
// Internet address.
struct in_addr {
u_int32_t s_addr; // address in network byte order
};
Internet address and port number are to be in a format, called the
"network byte order".
When the members of a IPv4 address have been initialised, the newly
created socket is associated with this address, with [ bind ] system
call. [ bind ] call sets a local IP address and port number of the
socket. When it is needed to assign a specific port ( well-known) to a
socket, [bind] is used. Well-known ports are used by servers. [ bind ]
call is mainly used by servers.
[bind] call takes three arguments
int = bind( socket-descriptor,
address of local IPv4 address,
size of the IPv4 address in bytes )
You may read manual of bind(2)] for the exact syntax of the call.
[listen] system call makes a [socket] ready to accept incoming client
requests. [ listen ] call also sets a limit of the incoming connection
queue. [listen] call is valid for connection oriented protocols (TCP).
In the next program [f2.c] following are done:
One TCP and one UDP
socket are created. Members of the structure of one IPv4 address are
then initialised. This address is assigned to the UDP and TCP sockets.
Although the same IP address and port number are used, the two sockets
are bound to two different addresses, as two different protocols are
used. The TCP [socket] is put in listening state.
------------------------------------------------------------
// file-name f2.c
// bind() and listen() calls
// usage: program-name
#include
#include
#include
#include
#include
#define LOCAL_ADDRESS "127.0.0.1"
// 127.0.0.1 is the IP address of loopback interface
// Any free port ( 1024 to 65535 ) is chosen
#define LOCAL_PORT 65432
int main ( void )
{
int sd1, sd2 ;
int n;
struct sockaddr_in addr; // IPv4 address
// members of [addr] are initialised
addr.sin_family = AF_INET;
addr.sin_port = htons( LOCAL_PORT );
n = inet_aton( LOCAL_ADDRESS , &(addr.sin_addr) );
if( n == 0 )
{
printf("invalid-addr\n");
exit(1);
}
// TCP ( IPv4 stream ) socket is created
sd1 = socket( PF_INET, SOCK_STREAM, IPPROTO_TCP );
// TCP socket is bound to a local address
n = bind( sd1, ( struct sockaddr *) &addr, sizeof(addr) );
if( n == -1 ) { perror("bind-call-1"); exit(1); }
// TCP socket is put in listening state
n = listen( sd1, 5 );
if( n == -1 ) { perror("listen-call"); exit(1); }
// UDP ( IPv4 datagram ) socket is created
sd2 = socket( PF_INET, SOCK_DGRAM, IPPROTO_UDP );
// UDP socket is bound to a local address
n = bind( sd2, ( struct sockaddr *) &addr, sizeof(addr) );
if( n == -1 ) { perror("bind-call-2"); exit(1); }
// endless loop
while( 1 ) { sleep(1); }
return 0;
} //end of main
---------------1---------------------------------------------
htons() function:
This function converts the short integer from host
byte order to network byte order. Port numbers are 16 bit long.
Read its manual.
$ man 3 htons
inet_aton() function:
This function converts the Internet host address
from the standard numbers-and-dots notation into binary data and
stores it in the address structure. This function returns nonzero if
the address is valid, zero if not.
Read its manual.
$ man 3 inet_aton
Assignment-3:
Compile and run the program.
$ gcc -Wall ./f2.c -o ./two-a
$ ./two-a
Use the following command and examine the output
$ netstat -an
You should get the following two lines related to your program.
Proto Local Address Foreign Address State
tcp 127.0.0.1:65432 0.0.0.0:* LISTEN
udp 127.0.0.1:65432 0.0.0.0:*
In [ f2.c ], the sockets were bound with loopback interface address
127.0.0.1 . If a server uses such a local address, only the users of
that host would be able to access the server.
Terminate the program with CTRL-C.
Replace the string "127.0.0.1" in [f2.c ] with IP address of ethernet
interface of your host.
Compile and run the program
$ gcc -Wall ./f2.c -o two-b
$ ./two-b
In another terminal, record the protocol, local-address and local-port
used by your program.
$ netstat -an
protocol local-address:local-port State
tcp _____________:65432
udp _____________:65432
Terminate the program with CTRL-C.
Use IP address of ethernet interface of your friend's host.
Compile the program
$ gcc -Wall ./f2.c -o ./two-c
Try to run the program
$ ./two-c
[bind] call should fail as such address was not found on the [ eth0 ]
interface of your host.
End of Assignment-3.
A server usually accepts service request, on all available interfaces
of a host. A server binds the socket with addresses of all interfaces
as local addresses.
The program [f3.c] shows such use.
------------------------------------------------------------
// file-name f3.c
// binding with all interfaces
// usage: program-name
#include
#include
#include
#include
#include
#define LOCAL_PORT 65432
int main ( void )
{
int sd1, sd2 ;
int n;
struct sockaddr_in addr; // IPv4 address
// members of [addr] are initialised
addr.sin_family = AF_INET;
addr.sin_port = htons( LOCAL_PORT );
addr.sin_addr.s_addr = htonl( INADDR_ANY );
// TCP ( IPv4 stream ) socket is created
sd1 = socket( PF_INET, SOCK_STREAM, IPPROTO_TCP );
// TCP socket is bound to a local address
n = bind( sd1, ( struct sockaddr *) &addr, sizeof(addr) );
if( n == -1 ) { perror("bind-call-1"); exit(1); }
// TCP socket is put in listening state
n = listen( sd1, 5 );
if( n == -1 ) { perror("listen-call"); exit(1); }
// UDP ( IPv4 datagram ) socket is created
sd2 = socket( PF_INET, SOCK_DGRAM, IPPROTO_UDP );
// UDP socket is bound to a local address
n = bind( sd2, ( struct sockaddr *) &addr, sizeof(addr) );
if( n == -1 ) { perror("bind-call-2"); exit(1); }
// endless loop
while( 1 ) { sleep(1); }
return 0;
} //end of main
------------------------------------------------------------
htonl() function:
This function converts the long integer from host
byte order to network byte order.
Read its manual.
$ man 3 htonl
Assignment-4:
Compile and run the program
$ gcc -Wall ./f3.c -o ./three
$ ./three
In another terminal, find out local [socket] addresses.
$ netstat -an
tcp 0.0.0.0:65432
udp 0.0.0.0:65432
The address 0.0.0.0 means that the socket is bound to all interfaces
of the host.
Verify this by scanning port 65432 of [lo] interface for TCP and UDP.
# nmap -sTU 127.0.0.1 -p 65432
Likely output is shown:
Interesting ports on localhost (127.0.0.1):
Port State Service
65432/tcp open unknown
65432/udp open unknown
[ eth0 ] interface is also scanned. Replace 172.16.2.146 with the IP
address of the [eth0] interface of your host.
# nmap -sTU 172.16.2.146 -p 65432
Likely output is shown:
Interesting ports on cc-146.cc.cemk.ac.in (172.16.2.146):
Port State Service
65432/tcp open unknown
65432/udp open unknown
Terminate the running program with CTRL-C
End of Assignment-4.
The next program [f4.c] is a TCP [echo] server. This [echo] server is
not using the well-known port ( 7 ), as this is an experiment.
---------------------------------------------------------------------
// file-name f4.c
// TCP ECHO server( iterative )
// usage: program-name
#include
#include
#include
#include
#include
#define LOCAL_PORT 65432
#define BUFFERSIZE 1024 // arbitrary
int main ( void )
{
int serv_sd; // socket descriptor
int temp_sd; // socket descriptor
int n;
struct sockaddr_in serv_addr; // IPv4 address
char buffer[BUFFERSIZE];
ssize_t i,j;
// members of [serv_addr] are initialised
serv_addr.sin_family = AF_INET;
serv_addr.sin_port = htons( LOCAL_PORT );
serv_addr.sin_addr.s_addr = htonl( INADDR_ANY );
// TCP ( IPv4 stream ) socket is created
serv_sd = socket( PF_INET, SOCK_STREAM, IPPROTO_TCP );
if( serv_sd == -1 ) { perror("socket-call"); exit(1);}
// TCP socket is bound to a local address
n = bind( serv_sd,
( struct sockaddr *) &serv_addr,
sizeof(serv_addr) );
if( n == -1 ) { perror("bind-call"); exit(1); }
// TCP socket is put in listening state
n = listen( serv_sd, 5 );
if( n == -1 ) { perror("listen-call"); exit(1); }
// server accepts client's request in an endless loop
while( 1 )
{
printf( "server: accepting request on TCP port %u\n",
LOCAL_PORT );
temp_sd = accept( serv_sd, NULL, 0 );
if( temp_sd == -1 ) { perror("accept-call"); }
// fill up the buffer with null characters before storing into it
memset( buffer, '\0', BUFFERSIZE );
// read clients request string in the buffer
i = read( temp_sd, buffer, BUFFERSIZE );
printf("server: %u bytes received from client\n", i );
// write the contents of the buffer in the [temp_sd]
j = write( temp_sd, buffer, i );
if( j == -1 ) { perror("write-call"); }
// shutdown both way communication on [temp_sd]
shutdown( temp_sd, SHUT_RDWR );
// remove the now useless [temp_sd]
close( temp_sd );
} //end of endless loop
return 0;
} //end of main
----------------------------------------------------------------------
accept() system call:
This call has three arguments. This call blocks
until a client request arrives on the server's socket. When a request
comes, the call returns a new socket file descriptor. This descriptor
is used for communication with the client.
Read its manual for full description of the call.
$ man 2 accept
In [f4.c], use of 2nd and 3rd arguments are not shown.
Assignment-5:
Compile and run the program.
$ gcc -Wall ./f4.c -o ./four
$ ./four
Request your friend to connect to your [echo] server, using [ telnet ]
client program. Replace 172.16.2.146 with IP address of [ eth0 ]
interface of your host.
friend $ telnet 172.16.2.146 65432
Did your friend get the echo ? ( Y / n )
Stop the [echo] server with CTRL-C.
End of Assignment-5.
TCP [echo] client:
The system calls to be executed by the client and
server, for connection oriented protocol, are repeated below.
SERVER
| CLIENT
socket(), bind(), listen(), accept() |
socket()
| connection establishment |
|<-----------------------------------> connect()
| |
read() <-------------------------------- write()
| data (request from client) |
| |
process client's request |
| |
write()-----------------------------------> read()
data (reply from server)
Figure-1
The program [f5.c] is the TCP [echo] client. This program has to call
[socket] and [connect] calls to establish connection with a server.
Then the client sends request to server and reads reply from server.
In [ f5.c ] the IP address of the [ echo ] server and TCP port of the
[echo] server are supplied as arguments to the program. We know that
assigned number of [echo] server is 7. Still we are using port number
as an argument to the client program. This would enable us to connect
to experimental [echo] servers or to any standard [echo] server.
Save the following file as [f5.c]
-------------------------------------------------------------------
// file-name f5.c
// TCP echo client
// usage -> program-name server-address server-port
#include
#include
#include
#include
#include
#include
#include
#define BUFFERSIZE 1024 // arbitrary
int main(int argc, char *argv[])
{
int sd; // used as socket descriptor
ssize_t i,j;
int n; // used to check returned value
char buffer[BUFFERSIZE];
struct sockaddr_in server_addr; // An IPv4 address
if( argc != 3 )
{
printf("Usage: %s server-address server-port \n", argv[0] );
printf("Example: %s 172.16.2.148 12345 \n", argv[0] );
exit(1);
}
// A TCP ( IPv4 stream ) socket is created.
sd = socket( PF_INET, SOCK_STREAM, IPPROTO_TCP );
if( sd == -1 ) { perror("socket-call"); exit( 1 ); }
server_addr.sin_family = AF_INET;
server_addr.sin_port = htons( atoi(argv[2]) );
n = inet_aton( argv[1], &(server_addr.sin_addr) );
if( n == 0 ) { printf("Invalid address\n"); exit(1); }
n = connect( sd, (struct sockaddr *) &server_addr,
sizeof(server_addr) );
if( n == -1 ) { perror("connect-call"); exit(1); }
/*
The local address of the socket was not set.
[bind()] system call was not called on [sd] before [ connect() ]
system call. As [connect()] was called on a unbound socket, [sd]
was automatically bound to a random free port ( ephemeral port )
with the local address set to [INADDR_ANY].
*/
// generate a prompt
write( STDOUT_FILENO, "Enter the string:", 17 );
// clear buffer before reading
memset( buffer, '\0', BUFFERSIZE );
// read from keyboard in the buffer
i = read( STDIN_FILENO, buffer, BUFFERSIZE );
if( i == -1 ) { perror("read1"); exit(1); }
printf( "bytes read from keyboard=%u\n", i );
// write contents of buffer on server's socket
j = write( sd, buffer, i );
if( j == -1 ) { perror("write1"); exit(1); }
printf("bytes written in server's socket=%u\n",j);
// clear buffer before reading
memset( buffer, '\0', BUFFERSIZE );
// read from server's socket into buffer
i = read( sd, buffer, BUFFERSIZE );
if( i == -1 ) { perror("read2"); exit(1); }
printf("bytes read from server's socket=%un", i );
write( STDOUT_FILENO,"Reply from echo server->", 24 );
j = write( STDOUT_FILENO, buffer, i );
if( j == -1 ) { perror("write2"); exit(1); }
// Shutdown the both-way ( duplex ) connection.
shutdown(sd, SHUT_RDWR);
exit(0);
}
-------------------------------------------------------------------
Function [htons()] takes integer argument. The port number ( argv[2] )
entered as character, is converted into integer.
Assignment-6:
Compile the program
$ gcc -Wall ./f5.c -o ./five
Run the program using wrong number of arguments to see usage message
$ ./five
$ ./five 172.16.2.251
Run the program correctly. Replace 172.16.2.251 with any standard
[echo] server's address. Do not enter a string now.
$ ./five 172.16.2.251 7
From another terminal use [ # netstat -tnp ] command. From the output
of the command, record the line related to your program
Proto Local Address Foreign Address State PID/Program name
Enter a string in the [ echo ] client program. It should be echoed on
your terminal.
Try to connect to a non-existent TCP server in localhost or in another
host. The [ connect ] call of your program should fail with a suitable
error message.
$ ./five 127.0.0.1 2000
$ ./five 172.16.2.251 7777
Try to connect to TCP [echo] servers running on different hosts in the
laboratory or outside the laboratory. Your TCP [echo] client program
should work if TCP [echo] servers are enabled in the specified hosts.
$ ./five 127.0.0.1 7
$ ./five 172.16.2.251 7
$ ./five 172.16.2.252 7
$ ./five 172.16.2.160 7
$ ./five 172.16.1.100 7
$ ./five 210.212.4.3 7
Try to connect to TCP [ echo ] servers running on friend's ECHO server
$ ./five 172.16.2.157 65432
End of Assignment-6.
----------------------------
Optional Assignment-1:
Rename the executable [five] as [tcp-echo-client].
$ mv ./five ./tcp-echo-client
Create a directory [bin] under your home directory
$ mkdir $HOME/bin
Copy the executable in [bin] directory
$ cp ./tcp-echo-client $HOME/bin/
Include the [bin] directory in [PATH] environmental variable
$ PATH=$PATH:$HOME/bin/
Check the intended inclusion with any of the following two commands.
$ echo $PATH
$ env
If the inclusion is correct, you should be able to run the TCP client
from any directory of your account. If you intend to include the [bin]
directory in PATH variable, on every login, include the following line
at the end of file [.bash_profile], in your home directory.
#-- .bash_profile file --
.
.
.
PATH=$PATH:$HOME/bin/
#---------------------------
1. UNIX Network Programming
By W. Richard Stevens
Chapter-6, on Berkeley Sockets
2. Manuals socket(2), ip(7),
tcp(7) and udp(7)
Square brackets are used to separate keywords, such as filenames,
programs names etc etc from lines of text. They have no other meaning.
Go to your home directory
$ cd
Verify the current directory
$ pwd
Create directory [socket1] in your home directory.
$ mkdir socket1
Change into [socket1] directory
$ cd socket1
Bring the file [socket1.txt] in this directory using NFS
$ mount /ftp-server
$ cd /ftp-server
.
.
You may also use [ftp] to bring the file.
SOCKET:
A socket is an endpoint for communication. Sockets are the
primary means of communicating with other hosts; telnet, rlogin, ftp,
talk and the other familiar network programs use sockets.
Different types of [socket]s can be created by [socket()] system call.
Consult the manual of this system call from section 2 of manual.
$ man 2 socket
[socket()] call takes three arguments. An unsigned integer is returned
when the call is successful. This integer is the file descriptor of
the socket. As with regular file descriptors, writing in the socket,
reading from the socket, closing the socket etc etc can be done, using
this descriptor.
Type of the created socket depends on the arguments used. In this
laboratory, we are going to use sockets suitable for network communic-
ation using IPv4 Internet protocols. From the above manual we find
that we have to consult the manual of [ip] from section 7 of the UNIX
manual, for the arguments to be used for creating IPv4 sockets.
$ man 7 ip
A TCP socket ( IPv4 stream socket ) can be created with...
tcp_socket = socket(PF_INET, SOCK_STREAM, IPPROTO_TCP);
An UDP socket ( IPv4 datagram socket ) can be created with...
udp_socket = socket(PF_INET, SOCK_DGRAM, IPPROTO_UDP);
Zero may be used to replace IPPROTO_TCP and IPPROTO_UDP. Zero is IP
pseudo protocol number.
We are not going to use [raw_socket] in this experiment.
Save the following program as [f1.c].
---------------------------------------------------------------------
// file-name f1.c
// One TCP and one UDP socket are created
// usage: program-name
#include
#include
#include
#include
int main ( void )
{
int sd1, sd2 ;
// sd1 and sd2 would be used as socket-file-descriptors
// Values of two symbolic constants are printed
printf("IPPROTO_TCP = %u \n", IPPROTO_TCP );
printf("IPPROTO_UDP = %u \n", IPPROTO_UDP );
// process number of this program
printf("PID = %u \n", getpid() );
// TCP ( IPv4 stream ) socket is created
sd1 = socket( PF_INET, SOCK_STREAM, IPPROTO_TCP );
// Numerical value of the socket descriptor is printed
printf("value of TCP socket descriptor = %u \n", sd1 );
// UDP ( IPv4 datagram ) socket is created
sd2 = socket( PF_INET, SOCK_DGRAM, IPPROTO_UDP );
// Numerical value of the socket descriptor is printed
printf("value of UDP socket descriptor = %u \n", sd2 );
// If the program exits, operating system closes (removes) the
// descriptors. The following endless loop is used for checking
// the creation of the two sockets.
while( 1 ) { sleep(1); }
return 0;
} //end of main
---------------------------------------------------------------------
Assignment-1:
Compile the program
$ gcc -Wall ./f1.c -o ./one
Run the executable program, do not terminate the program and record
the following from the output of the program:
$ ./one
IPPROTO_TCP = ___
IPPROTO_UDP = ___
PID = ________
value of TCP socket descriptor = ___
value of UDP socket descriptor = ___
As the program runs in this terminal, this terminal is unusable now.
Note: The program can be started in background also.
$ ./one &
If the program runs in the background, this terminal becomes
usable.
Verify the PID of your program
$ ps ax | grep one
In another terminal, examine the file [/etc/protocols] and record the
following
$ less /etc/protocols
protocols-name protocols-number
IP ------------> ___
TCP -----------> ___
UDP -----------> ___
Check the creation of the sockets with the following command
$ ls -l /proc/value-of-PID/fd
Were the two sockets created ? ( Y / n )
Terminate the running program [one] with CTRL-C.
End of Assignment-1.
5-tuple association for network communication may be stated as:
(protocol,local-address,local-process,foreign-address,foreign-process)
Assignment-2.
In this assignment, a 5-tuple association for network
communication is to be verified. The [echo] server process using TCP,
running in your friend's host, are the [ foreign-address ], [ foreign-
process ] and [ protocol ].
Examine file [/etc/services] and record:
$ less /etc/services
[echo] server, using TCP protocol, runs on port number ____ .
[foreign-process] is NOT the PID of the [echo] server process, but it
is the port number, the [echo] server process associates with. If the
[ echo ] server process is restarted, its PID would change but its
association with port number - 7 would be unaltered. This port number
is well-known to the [ client/clients ].
At present we do not have any TCP [echo] client program. Later in this
experiment we are going to write a TCP [echo] client program.
[telnet] is a [client] program used to connect to the [telnetd] server
program. [ telnet ] connects to port-23 of the specified host, if port
number is not specified. If port number is specified, [ telnet ]
connects to that port.
The two commands should give the same result
$ telnet 192.168.5.145
or
$ telnet 172.16.2.145 23
If port number is specified as 7, [ telnet ] program may be used to
communicate with the [echo] server. Replace 172.16.2.145 with the IP
address of your friend's host.
$ telnet 172.16.2.145 7
Enter any string. It should be echoed on your terminal.
[ telnet ] program used in your host, is the [ local-process ]. PID of
[telnet] process is NOT the [[local-process], it is the port number it
is associated with. This port number ( in the range 1024 - 65535 ) is
alloted to that instance of [telnet] process, by the operating system
and it is guaranteed to be free, no other process using TCP protocol
was using it. The port assigned to the [ client ] process is called
ephemeral ( short lived ) port. The PID and the ephemeral port might
change with each invocation of the [client] process.
----------- ----------------
| | | |
| Your host |_____________________| Friend's Host |
| client | | echo server(7) |
| | | |
----------- ----------------
Connect to the [ echo ] server of your friend but do not enter any
string. In this condition a TCP connection is established.
$ telnet 172.16.2.145 7
In another terminal, login in your account ( or login as [root] ) and
use the following command.
$ ps ax
PID of the [telnet] process -->
Use the following command...
$ netstat -atnp
You may read manual of this command [ $ man 8 netstat ].
The meaning of the options are reproduced from the manual:
a all
t TCP
n numeric output
p show PID and program name
If the output is more than one screenful, you can store the result in
a file and examine the file with a pager, such as [less].
$ netstat -atnp >tmp 2>&1
$ less ./tmp
Fill up the following table.
proto loc-add:loc-port for-add:for-port state PID/prog-name
tcp :7 ESTABLISHED
The above is the 5-tuple association.
End of Assignment-2.
The system calls used by the [server] and the [client] for connection
oriented protocol are shown below ( From "UNIX Network Programming" by
W.Richard Stevens ). TCP is a connection oriented protocol.
SERVER
socket()
|
bind()
|
listen()
|
accept() CLIENT
|
Blocks until connection socket()
from client |
| connection establishment |
|<-----------------------------------------> connect()
| |
read() <------------------------------------- write()
| data (request from client) |
| |
process client's request |
| |
write() --------------------------------------> read()
data (reply from server)
A newly created socket is not useful for communication. An address is
to be assigned to it.
The format of a IPv4 address is reproduces from manual [ip(7)].
struct sockaddr_in
{
sa_family_t sin_family; // address family: AF_INET
u_int16_t sin_port; // port in network byte
struct in_addr sin_addr; // internet address
};
// Internet address.
struct in_addr {
u_int32_t s_addr; // address in network byte order
};
Internet address and port number are to be in a format, called the
"network byte order".
When the members of a IPv4 address have been initialised, the newly
created socket is associated with this address, with [ bind ] system
call. [ bind ] call sets a local IP address and port number of the
socket. When it is needed to assign a specific port ( well-known) to a
socket, [bind] is used. Well-known ports are used by servers. [ bind ]
call is mainly used by servers.
[bind] call takes three arguments
int = bind( socket-descriptor,
address of local IPv4 address,
size of the IPv4 address in bytes )
You may read manual of bind(2)] for the exact syntax of the call.
[listen] system call makes a [socket] ready to accept incoming client
requests. [ listen ] call also sets a limit of the incoming connection
queue. [listen] call is valid for connection oriented protocols (TCP).
In the next program [f2.c] following are done:
One TCP and one UDP
socket are created. Members of the structure of one IPv4 address are
then initialised. This address is assigned to the UDP and TCP sockets.
Although the same IP address and port number are used, the two sockets
are bound to two different addresses, as two different protocols are
used. The TCP [socket] is put in listening state.
------------------------------------------------------------
// file-name f2.c
// bind() and listen() calls
// usage: program-name
#include
#include
#include
#include
#include
#define LOCAL_ADDRESS "127.0.0.1"
// 127.0.0.1 is the IP address of loopback interface
// Any free port ( 1024 to 65535 ) is chosen
#define LOCAL_PORT 65432
int main ( void )
{
int sd1, sd2 ;
int n;
struct sockaddr_in addr; // IPv4 address
// members of [addr] are initialised
addr.sin_family = AF_INET;
addr.sin_port = htons( LOCAL_PORT );
n = inet_aton( LOCAL_ADDRESS , &(addr.sin_addr) );
if( n == 0 )
{
printf("invalid-addr\n");
exit(1);
}
// TCP ( IPv4 stream ) socket is created
sd1 = socket( PF_INET, SOCK_STREAM, IPPROTO_TCP );
// TCP socket is bound to a local address
n = bind( sd1, ( struct sockaddr *) &addr, sizeof(addr) );
if( n == -1 ) { perror("bind-call-1"); exit(1); }
// TCP socket is put in listening state
n = listen( sd1, 5 );
if( n == -1 ) { perror("listen-call"); exit(1); }
// UDP ( IPv4 datagram ) socket is created
sd2 = socket( PF_INET, SOCK_DGRAM, IPPROTO_UDP );
// UDP socket is bound to a local address
n = bind( sd2, ( struct sockaddr *) &addr, sizeof(addr) );
if( n == -1 ) { perror("bind-call-2"); exit(1); }
// endless loop
while( 1 ) { sleep(1); }
return 0;
} //end of main
---------------1---------------------------------------------
htons() function:
This function converts the short integer from host
byte order to network byte order. Port numbers are 16 bit long.
Read its manual.
$ man 3 htons
inet_aton() function:
This function converts the Internet host address
from the standard numbers-and-dots notation into binary data and
stores it in the address structure. This function returns nonzero if
the address is valid, zero if not.
Read its manual.
$ man 3 inet_aton
Assignment-3:
Compile and run the program.
$ gcc -Wall ./f2.c -o ./two-a
$ ./two-a
Use the following command and examine the output
$ netstat -an
You should get the following two lines related to your program.
Proto Local Address Foreign Address State
tcp 127.0.0.1:65432 0.0.0.0:* LISTEN
udp 127.0.0.1:65432 0.0.0.0:*
In [ f2.c ], the sockets were bound with loopback interface address
127.0.0.1 . If a server uses such a local address, only the users of
that host would be able to access the server.
Terminate the program with CTRL-C.
Replace the string "127.0.0.1" in [f2.c ] with IP address of ethernet
interface of your host.
Compile and run the program
$ gcc -Wall ./f2.c -o two-b
$ ./two-b
In another terminal, record the protocol, local-address and local-port
used by your program.
$ netstat -an
protocol local-address:local-port State
tcp _____________:65432
udp _____________:65432
Terminate the program with CTRL-C.
Use IP address of ethernet interface of your friend's host.
Compile the program
$ gcc -Wall ./f2.c -o ./two-c
Try to run the program
$ ./two-c
[bind] call should fail as such address was not found on the [ eth0 ]
interface of your host.
End of Assignment-3.
A server usually accepts service request, on all available interfaces
of a host. A server binds the socket with addresses of all interfaces
as local addresses.
The program [f3.c] shows such use.
------------------------------------------------------------
// file-name f3.c
// binding with all interfaces
// usage: program-name
#include
#include
#include
#include
#include
#define LOCAL_PORT 65432
int main ( void )
{
int sd1, sd2 ;
int n;
struct sockaddr_in addr; // IPv4 address
// members of [addr] are initialised
addr.sin_family = AF_INET;
addr.sin_port = htons( LOCAL_PORT );
addr.sin_addr.s_addr = htonl( INADDR_ANY );
// TCP ( IPv4 stream ) socket is created
sd1 = socket( PF_INET, SOCK_STREAM, IPPROTO_TCP );
// TCP socket is bound to a local address
n = bind( sd1, ( struct sockaddr *) &addr, sizeof(addr) );
if( n == -1 ) { perror("bind-call-1"); exit(1); }
// TCP socket is put in listening state
n = listen( sd1, 5 );
if( n == -1 ) { perror("listen-call"); exit(1); }
// UDP ( IPv4 datagram ) socket is created
sd2 = socket( PF_INET, SOCK_DGRAM, IPPROTO_UDP );
// UDP socket is bound to a local address
n = bind( sd2, ( struct sockaddr *) &addr, sizeof(addr) );
if( n == -1 ) { perror("bind-call-2"); exit(1); }
// endless loop
while( 1 ) { sleep(1); }
return 0;
} //end of main
------------------------------------------------------------
htonl() function:
This function converts the long integer from host
byte order to network byte order.
Read its manual.
$ man 3 htonl
Assignment-4:
Compile and run the program
$ gcc -Wall ./f3.c -o ./three
$ ./three
In another terminal, find out local [socket] addresses.
$ netstat -an
tcp 0.0.0.0:65432
udp 0.0.0.0:65432
The address 0.0.0.0 means that the socket is bound to all interfaces
of the host.
Verify this by scanning port 65432 of [lo] interface for TCP and UDP.
# nmap -sTU 127.0.0.1 -p 65432
Likely output is shown:
Interesting ports on localhost (127.0.0.1):
Port State Service
65432/tcp open unknown
65432/udp open unknown
[ eth0 ] interface is also scanned. Replace 172.16.2.146 with the IP
address of the [eth0] interface of your host.
# nmap -sTU 172.16.2.146 -p 65432
Likely output is shown:
Interesting ports on cc-146.cc.cemk.ac.in (172.16.2.146):
Port State Service
65432/tcp open unknown
65432/udp open unknown
Terminate the running program with CTRL-C
End of Assignment-4.
The next program [f4.c] is a TCP [echo] server. This [echo] server is
not using the well-known port ( 7 ), as this is an experiment.
---------------------------------------------------------------------
// file-name f4.c
// TCP ECHO server( iterative )
// usage: program-name
#include
#include
#include
#include
#include
#define LOCAL_PORT 65432
#define BUFFERSIZE 1024 // arbitrary
int main ( void )
{
int serv_sd; // socket descriptor
int temp_sd; // socket descriptor
int n;
struct sockaddr_in serv_addr; // IPv4 address
char buffer[BUFFERSIZE];
ssize_t i,j;
// members of [serv_addr] are initialised
serv_addr.sin_family = AF_INET;
serv_addr.sin_port = htons( LOCAL_PORT );
serv_addr.sin_addr.s_addr = htonl( INADDR_ANY );
// TCP ( IPv4 stream ) socket is created
serv_sd = socket( PF_INET, SOCK_STREAM, IPPROTO_TCP );
if( serv_sd == -1 ) { perror("socket-call"); exit(1);}
// TCP socket is bound to a local address
n = bind( serv_sd,
( struct sockaddr *) &serv_addr,
sizeof(serv_addr) );
if( n == -1 ) { perror("bind-call"); exit(1); }
// TCP socket is put in listening state
n = listen( serv_sd, 5 );
if( n == -1 ) { perror("listen-call"); exit(1); }
// server accepts client's request in an endless loop
while( 1 )
{
printf( "server: accepting request on TCP port %u\n",
LOCAL_PORT );
temp_sd = accept( serv_sd, NULL, 0 );
if( temp_sd == -1 ) { perror("accept-call"); }
// fill up the buffer with null characters before storing into it
memset( buffer, '\0', BUFFERSIZE );
// read clients request string in the buffer
i = read( temp_sd, buffer, BUFFERSIZE );
printf("server: %u bytes received from client\n", i );
// write the contents of the buffer in the [temp_sd]
j = write( temp_sd, buffer, i );
if( j == -1 ) { perror("write-call"); }
// shutdown both way communication on [temp_sd]
shutdown( temp_sd, SHUT_RDWR );
// remove the now useless [temp_sd]
close( temp_sd );
} //end of endless loop
return 0;
} //end of main
----------------------------------------------------------------------
accept() system call:
This call has three arguments. This call blocks
until a client request arrives on the server's socket. When a request
comes, the call returns a new socket file descriptor. This descriptor
is used for communication with the client.
Read its manual for full description of the call.
$ man 2 accept
In [f4.c], use of 2nd and 3rd arguments are not shown.
Assignment-5:
Compile and run the program.
$ gcc -Wall ./f4.c -o ./four
$ ./four
Request your friend to connect to your [echo] server, using [ telnet ]
client program. Replace 172.16.2.146 with IP address of [ eth0 ]
interface of your host.
friend $ telnet 172.16.2.146 65432
Did your friend get the echo ? ( Y / n )
Stop the [echo] server with CTRL-C.
End of Assignment-5.
TCP [echo] client:
The system calls to be executed by the client and
server, for connection oriented protocol, are repeated below.
SERVER
| CLIENT
socket(), bind(), listen(), accept() |
socket()
| connection establishment |
|<-----------------------------------> connect()
| |
read() <-------------------------------- write()
| data (request from client) |
| |
process client's request |
| |
write()-----------------------------------> read()
data (reply from server)
Figure-1
The program [f5.c] is the TCP [echo] client. This program has to call
[socket] and [connect] calls to establish connection with a server.
Then the client sends request to server and reads reply from server.
In [ f5.c ] the IP address of the [ echo ] server and TCP port of the
[echo] server are supplied as arguments to the program. We know that
assigned number of [echo] server is 7. Still we are using port number
as an argument to the client program. This would enable us to connect
to experimental [echo] servers or to any standard [echo] server.
Save the following file as [f5.c]
-------------------------------------------------------------------
// file-name f5.c
// TCP echo client
// usage -> program-name server-address server-port
#include
#include
#include
#include
#include
#include
#include
#define BUFFERSIZE 1024 // arbitrary
int main(int argc, char *argv[])
{
int sd; // used as socket descriptor
ssize_t i,j;
int n; // used to check returned value
char buffer[BUFFERSIZE];
struct sockaddr_in server_addr; // An IPv4 address
if( argc != 3 )
{
printf("Usage: %s server-address server-port \n", argv[0] );
printf("Example: %s 172.16.2.148 12345 \n", argv[0] );
exit(1);
}
// A TCP ( IPv4 stream ) socket is created.
sd = socket( PF_INET, SOCK_STREAM, IPPROTO_TCP );
if( sd == -1 ) { perror("socket-call"); exit( 1 ); }
server_addr.sin_family = AF_INET;
server_addr.sin_port = htons( atoi(argv[2]) );
n = inet_aton( argv[1], &(server_addr.sin_addr) );
if( n == 0 ) { printf("Invalid address\n"); exit(1); }
n = connect( sd, (struct sockaddr *) &server_addr,
sizeof(server_addr) );
if( n == -1 ) { perror("connect-call"); exit(1); }
/*
The local address of the socket was not set.
[bind()] system call was not called on [sd] before [ connect() ]
system call. As [connect()] was called on a unbound socket, [sd]
was automatically bound to a random free port ( ephemeral port )
with the local address set to [INADDR_ANY].
*/
// generate a prompt
write( STDOUT_FILENO, "Enter the string:", 17 );
// clear buffer before reading
memset( buffer, '\0', BUFFERSIZE );
// read from keyboard in the buffer
i = read( STDIN_FILENO, buffer, BUFFERSIZE );
if( i == -1 ) { perror("read1"); exit(1); }
printf( "bytes read from keyboard=%u\n", i );
// write contents of buffer on server's socket
j = write( sd, buffer, i );
if( j == -1 ) { perror("write1"); exit(1); }
printf("bytes written in server's socket=%u\n",j);
// clear buffer before reading
memset( buffer, '\0', BUFFERSIZE );
// read from server's socket into buffer
i = read( sd, buffer, BUFFERSIZE );
if( i == -1 ) { perror("read2"); exit(1); }
printf("bytes read from server's socket=%un", i );
write( STDOUT_FILENO,"Reply from echo server->", 24 );
j = write( STDOUT_FILENO, buffer, i );
if( j == -1 ) { perror("write2"); exit(1); }
// Shutdown the both-way ( duplex ) connection.
shutdown(sd, SHUT_RDWR);
exit(0);
}
-------------------------------------------------------------------
Function [htons()] takes integer argument. The port number ( argv[2] )
entered as character, is converted into integer.
Assignment-6:
Compile the program
$ gcc -Wall ./f5.c -o ./five
Run the program using wrong number of arguments to see usage message
$ ./five
$ ./five 172.16.2.251
Run the program correctly. Replace 172.16.2.251 with any standard
[echo] server's address. Do not enter a string now.
$ ./five 172.16.2.251 7
From another terminal use [ # netstat -tnp ] command. From the output
of the command, record the line related to your program
Proto Local Address Foreign Address State PID/Program name
Enter a string in the [ echo ] client program. It should be echoed on
your terminal.
Try to connect to a non-existent TCP server in localhost or in another
host. The [ connect ] call of your program should fail with a suitable
error message.
$ ./five 127.0.0.1 2000
$ ./five 172.16.2.251 7777
Try to connect to TCP [echo] servers running on different hosts in the
laboratory or outside the laboratory. Your TCP [echo] client program
should work if TCP [echo] servers are enabled in the specified hosts.
$ ./five 127.0.0.1 7
$ ./five 172.16.2.251 7
$ ./five 172.16.2.252 7
$ ./five 172.16.2.160 7
$ ./five 172.16.1.100 7
$ ./five 210.212.4.3 7
Try to connect to TCP [ echo ] servers running on friend's ECHO server
$ ./five 172.16.2.157 65432
End of Assignment-6.
----------------------------
Optional Assignment-1:
Rename the executable [five] as [tcp-echo-client].
$ mv ./five ./tcp-echo-client
Create a directory [bin] under your home directory
$ mkdir $HOME/bin
Copy the executable in [bin] directory
$ cp ./tcp-echo-client $HOME/bin/
Include the [bin] directory in [PATH] environmental variable
$ PATH=$PATH:$HOME/bin/
Check the intended inclusion with any of the following two commands.
$ echo $PATH
$ env
If the inclusion is correct, you should be able to run the TCP client
from any directory of your account. If you intend to include the [bin]
directory in PATH variable, on every login, include the following line
at the end of file [.bash_profile], in your home directory.
#-- .bash_profile file --
.
.
.
PATH=$PATH:$HOME/bin/
#---------------------------
SMTP
Documents to read:
1. After the installation of the softwares, read the manuals with a
browser, such as [lynx].
$ lynx /usr/share/doc/exim/manual.html/oview.html
2. Manual of exim[8].
$ man 8 exim
3. Read HOWTO documents
$ zless /usr/share/doc/HOWTO/en-txt/Mail-Administrator-HOWTO.gz
4. Exim - The Mail Transfer Agent By Philip Hazel ( O'REILLY )
The following simplified block diagram shows how email goes from one
user to another.
sender -> MUA -> mail-spool -> MTA ->-
|
|TCP connection
|(localhost/network)
|
recipient <- MUA <- mailboxes <- MTA <-
Sender uses a Mail User Agent( MUA ) to submit mail to mail spool. The
Mail Transport Agent( MTA ) takes the mail from spool, establishes TCP
connection to the destination MTA and transfers the mail using SMTP
protocol. The MTA at sender's end is the client and the MTA at the
receiving side is the server in this situation. The receiving side MTA
takes the mail and stores it in the user's mailbox. MTA can function
both as a server and as a client.
Examples of MUA - mail, mutt, pine, elm etc etc
Examples of MTA - sendmail, exim, postfix, qmail etc etc.
SMTP - Simple Mail Transfer Protocol - SMTP is used to transfer
millions of email daily around the globe. An extended SMTP,
known as ESMTP is widely used. ESMTP is backward compatible
with SMTP
The basic operation of SMTP server ( Port 25 ) are:
1. Accept an incoming message
2. Check the addresses of the message
3. If the recipient is local, store the message for retrieval
4. If the recipient is remote, forward the message
5. If the message is undeliverable, return an error message to the
sender, explaining the problem
In this experiment [exim] is to be installed as MTA.
Create a directory [ mail ] in your home directory and carry out the
mail related experiments in that directory.
$ mkdir $HOME/mail
Bring the files
exim_3.35-1woody3_i386.deb - CD1
exim-doc-html_3.20-1_all.deb - CD4
libmailutils0_20020409-1_i386.deb - CD1
mailutils_20020409-1_i386.deb - CD1
in [mail] directory from anonymous FTP server of your laboratory.
Installation of SMTP server:
Some free Mail Transport Agents ( SMTP
servers) are available. Among them [sendmail] is most widely used but
it has complex configuration options. In this experiment, another MTA,
[exim] is to be installed. A VERY simple configuration of [exim] is to
be tested on Debian Linux platform.
Note: At present [exim] MTA is being used at CEMK.
Check status of installed MTA
$ dpkg -l | grep MTA
Remove installed MTA and its configuration file
# dpkg --purge sendmail
or
# dpkg --purge exim
However due to complex dependency among different files and programs,
removal of installed MTA is difficult. Remove the packages which are
preventing removal of the MTA.
Install [exim] binary
# dpkg -i ./exim_3.35-1woody3_i386.deb
Install exim documentation
# dpkg -i ./exim-doc-html_3.20-1_all.deb
Do not configure [exim] now. Select option (5) (No configuration)
A minimal configuration file is available. See that file
$ zless /usr/share/doc/exim/example.conf.gz
Save this file as [/etc/exim/my-conf]
# zcat /usr/share/doc/exim/example.conf.gz > \
> /etc/exim/my-conf
Edit [/etc/exim/my-conf]
--------------------- /etc/exim/my-conf ------------------------
# MAIN CONFIGURATION
primary_hostname = cc-146.cc.cemk.ac.in
local_domains = localhost : cc-146.cc.cemk.ac.in : cc-146
kkk # planted error
end
# TRANSPORTS CONFIGURATION
remote_smtp:
driver = smtp
local_delivery:
driver = appendfile
file = /var/mail/$local_part
delivery_date_add
envelope_to_add
return_path_add
group = mail
mode = 0660
address_pipe:
driver = pipe
return_output
address_file:
driver = appendfile
delivery_date_add
envelope_to_add
return_path_add
address_reply:
driver = autoreply
end
# DIRECTORS CONFIGURATION
system_aliases:
driver = aliasfile
file = /etc/aliases
search_type = lsearch
# user = exim
file_transport = address_file
pipe_transport = address_pipe
userforward:
driver = forwardfile
file = .forward
no_verify
no_expn
check_ancestor
# filter
file_transport = address_file
pipe_transport = address_pipe
reply_transport = address_reply
localuser:
driver = localuser
transport = local_delivery
end
# ROUTERS CONFIGURATION
lookuphost:
driver = lookuphost
transport = remote_smtp
ignore_target_hosts = 127.0.0.0/8
end
# RETRY CONFIGURATION
* * F,2h,15m; G,16h,1h,1.5; F,4d,8h
end
# REWRITE CONFIGURATION
# There are no rewriting specifications in this default
# configuration file.
end
# AUTHENTICATION CONFIGURATION
# There are no authenticator specifications in this default
# configuration file.
# End of Exim configuration file
----------------------------------------------------------------
Check syntax of this file if used as [exim] configuration file.
# /usr/sbin/exim -C /etc/exim/my-conf -bV
Remove errors if any and recheck
# /usr/sbin/exim -C /etc/exim/my-conf -bV
Start [exim]. It may not start in absence of a configuration file
# /etc/init.d/exim start
Copy [my-conf] as exim's configuration file.
# cp /etc/exim/my-conf /etc/exim/exim.conf
Start [exim].
# /etc/init.d/exim start
Install a simple MUA
# dpkg -i libmailutils0_20020409-1_i386.deb
# dpkg -i mailutils_20020409-1_i386.deb
Request your friends to send mail to you
friend $ mail sumit@cc-146 < /etc/resolv.conf
friend $ mail sumit@cc-146.cc.cemk.ac.in < /dev/null
Stop [exim].
# /etc/init.d/exim stop
Option [ -bd ] runs exim as daemon. With [ -q 2m ], the mail queue is
processed at intervals of two minutes. This value is not suitable for
real applications.
Though [sendmail] MTA is not installed, the following link is used to
point to the [exim] binary. Due to this link, [ exim ] can be started
using the method of starting [sendmail].
$ file /usr/lib/sendmail
Output->
Start exim using the above link.
# /usr/lib/sendmail -q1h10m
It is possible to communicate with MTA directly, using raw SMTP
commands, over a telnet session to Port 25. Port 25 is assigned to
SMTP. You may check [/etc/services].
Sending mail using raw SMTP commands:
Initiate a telnet session on Port 25 of your host, to talk to MTA
using raw SMTP commands.
$ telnet 172.16.2.145 25
Replace 172.16.2.145 with Ethernet interface of your machine.
A portion of typical screen output for this example is shown below.
The texts without a leading number are commands executed by you. The
MTAs at the two ends use these leading numbers for communication.
Examples:
220 is the greeting message.
500 is one error message
$ telnet 172.16.2.146 25
Trying 172.16.2.146...
Connected to 172.16.2.146.
Escape character is '^]'.
220 cc-146.cc.cemk.ac.in ESMTP Exim 3.35 #1 Mon, 17 Mar 2006 18:32:13
+0530
ehlo cc.cemk.ac.in
250-cc-146.cc.cemk.ac.in Hello sumit at cc.cemk.ac.in [172.16.2.146]
250-SIZE
250-PIPELINING
250 HELP
help
214-Commands supported:
214- HELO EHLO MAIL RCPT DATA AUTH
214 NOOP QUIT RSET HELP
mail from: sumit@cc-146
250 is syntactically correct
rcpt to: guest@cc-146
250 is syntactically correct
data
354 Enter message, ending with "." on a line by itself
This is test mail... sumit
.
250 OK id=1FKb9W-0000KY-00
quit
221 cc-146.cc.cemk.ac.in closing connection
Connection closed by foreign host.
Check the mail of [guest].
# mail -u guest
Send a mail to a friend in another host using SMTP commands.
Was it successful ? ( Y / n )
Mail aliases:
User [ sumit ] wants to receive mail as [ sumit ], [ sumitbasu ],
[ sumit-basu ] and [ sumit_basu ]. This can be done with the help of
aliasing.
Replace [ sumit ] with your-log-name.
Edit [/etc/mail/aliases] as under. Replace [sumit] with your-log-name.
#.. [/etc/mail/aliases] ...
sumitbasu: sumit
sumit-basu: sumit
sumit_basu: sumit
#.. [/etc/mail/aliases] ...
Build the alias database file from the alias text file. Typical screen
output is also shown.
# exim_dbmbuild /etc/aliases /etc/aliases.db
3 entries written
Verify the aliases users.
# /usr/sbin/exim -bv sumitbasu
sumit@cc-146.cc.cemk.ac.in verified
# /usr/sbin/exim -bv sumit-basu
sumit@cc-146.cc.cemk.ac.in verified
# /usr/sbin/exim -bv sumit_basu
sumit@cc-146.cc.cemk.ac.in verified
# /usr/sbin/exim -bv sumit
sumit@cc-146.cc.cemk.ac.in verified
Request a friend to send a mail to sumit_basu
$ mail sumit_basu@cc-146.cc.cemk.ac.in < /dev/null
Group mails:
The alias mechanism can be used to send mails to a group of users.
Edit [/etc/mail/aliases] as under
------- /etc/mail/aliases -------
sumitbasu: sumit
sumit-basu: sumit
sumit_basu: sumit
3year: :include:/etc/exim/3y
---------------------------------
Edit file [/etc/exim/3y] as under.
------ /etc/mail/3y ------
sumit@cc-140.cc.cemk.ac.in
sunil@cc-145.cc.cemk.ac.in
you@localhost
--------------------------
Build the alias database file from the alias text file.
# exim_dbmbuild /etc/aliases /etc/aliases.db
4 entries written
Check the user [3year]
# /usr/sbin/exim -bv 3year
Send a mail to the group...
$ mail -v 3year
Subject: Group Mail
Testing group mail
.
Cc:
Request the recipients to check their mails.
----------
1. After the installation of the softwares, read the manuals with a
browser, such as [lynx].
$ lynx /usr/share/doc/exim/manual.html/oview.html
2. Manual of exim[8].
$ man 8 exim
3. Read HOWTO documents
$ zless /usr/share/doc/HOWTO/en-txt/Mail-Administrator-HOWTO.gz
4. Exim - The Mail Transfer Agent By Philip Hazel ( O'REILLY )
The following simplified block diagram shows how email goes from one
user to another.
sender -> MUA -> mail-spool -> MTA ->-
|
|TCP connection
|(localhost/network)
|
recipient <- MUA <- mailboxes <- MTA <-
Sender uses a Mail User Agent( MUA ) to submit mail to mail spool. The
Mail Transport Agent( MTA ) takes the mail from spool, establishes TCP
connection to the destination MTA and transfers the mail using SMTP
protocol. The MTA at sender's end is the client and the MTA at the
receiving side is the server in this situation. The receiving side MTA
takes the mail and stores it in the user's mailbox. MTA can function
both as a server and as a client.
Examples of MUA - mail, mutt, pine, elm etc etc
Examples of MTA - sendmail, exim, postfix, qmail etc etc.
SMTP - Simple Mail Transfer Protocol - SMTP is used to transfer
millions of email daily around the globe. An extended SMTP,
known as ESMTP is widely used. ESMTP is backward compatible
with SMTP
The basic operation of SMTP server ( Port 25 ) are:
1. Accept an incoming message
2. Check the addresses of the message
3. If the recipient is local, store the message for retrieval
4. If the recipient is remote, forward the message
5. If the message is undeliverable, return an error message to the
sender, explaining the problem
In this experiment [exim] is to be installed as MTA.
Create a directory [ mail ] in your home directory and carry out the
mail related experiments in that directory.
$ mkdir $HOME/mail
Bring the files
exim_3.35-1woody3_i386.deb - CD1
exim-doc-html_3.20-1_all.deb - CD4
libmailutils0_20020409-1_i386.deb - CD1
mailutils_20020409-1_i386.deb - CD1
in [mail] directory from anonymous FTP server of your laboratory.
Installation of SMTP server:
Some free Mail Transport Agents ( SMTP
servers) are available. Among them [sendmail] is most widely used but
it has complex configuration options. In this experiment, another MTA,
[exim] is to be installed. A VERY simple configuration of [exim] is to
be tested on Debian Linux platform.
Note: At present [exim] MTA is being used at CEMK.
Check status of installed MTA
$ dpkg -l | grep MTA
Remove installed MTA and its configuration file
# dpkg --purge sendmail
or
# dpkg --purge exim
However due to complex dependency among different files and programs,
removal of installed MTA is difficult. Remove the packages which are
preventing removal of the MTA.
Install [exim] binary
# dpkg -i ./exim_3.35-1woody3_i386.deb
Install exim documentation
# dpkg -i ./exim-doc-html_3.20-1_all.deb
Do not configure [exim] now. Select option (5) (No configuration)
A minimal configuration file is available. See that file
$ zless /usr/share/doc/exim/example.conf.gz
Save this file as [/etc/exim/my-conf]
# zcat /usr/share/doc/exim/example.conf.gz > \
> /etc/exim/my-conf
Edit [/etc/exim/my-conf]
--------------------- /etc/exim/my-conf ------------------------
# MAIN CONFIGURATION
primary_hostname = cc-146.cc.cemk.ac.in
local_domains = localhost : cc-146.cc.cemk.ac.in : cc-146
kkk # planted error
end
# TRANSPORTS CONFIGURATION
remote_smtp:
driver = smtp
local_delivery:
driver = appendfile
file = /var/mail/$local_part
delivery_date_add
envelope_to_add
return_path_add
group = mail
mode = 0660
address_pipe:
driver = pipe
return_output
address_file:
driver = appendfile
delivery_date_add
envelope_to_add
return_path_add
address_reply:
driver = autoreply
end
# DIRECTORS CONFIGURATION
system_aliases:
driver = aliasfile
file = /etc/aliases
search_type = lsearch
# user = exim
file_transport = address_file
pipe_transport = address_pipe
userforward:
driver = forwardfile
file = .forward
no_verify
no_expn
check_ancestor
# filter
file_transport = address_file
pipe_transport = address_pipe
reply_transport = address_reply
localuser:
driver = localuser
transport = local_delivery
end
# ROUTERS CONFIGURATION
lookuphost:
driver = lookuphost
transport = remote_smtp
ignore_target_hosts = 127.0.0.0/8
end
# RETRY CONFIGURATION
* * F,2h,15m; G,16h,1h,1.5; F,4d,8h
end
# REWRITE CONFIGURATION
# There are no rewriting specifications in this default
# configuration file.
end
# AUTHENTICATION CONFIGURATION
# There are no authenticator specifications in this default
# configuration file.
# End of Exim configuration file
----------------------------------------------------------------
Check syntax of this file if used as [exim] configuration file.
# /usr/sbin/exim -C /etc/exim/my-conf -bV
Remove errors if any and recheck
# /usr/sbin/exim -C /etc/exim/my-conf -bV
Start [exim]. It may not start in absence of a configuration file
# /etc/init.d/exim start
Copy [my-conf] as exim's configuration file.
# cp /etc/exim/my-conf /etc/exim/exim.conf
Start [exim].
# /etc/init.d/exim start
Install a simple MUA
# dpkg -i libmailutils0_20020409-1_i386.deb
# dpkg -i mailutils_20020409-1_i386.deb
Request your friends to send mail to you
friend $ mail sumit@cc-146 < /etc/resolv.conf
friend $ mail sumit@cc-146.cc.cemk.ac.in < /dev/null
Stop [exim].
# /etc/init.d/exim stop
Option [ -bd ] runs exim as daemon. With [ -q 2m ], the mail queue is
processed at intervals of two minutes. This value is not suitable for
real applications.
Though [sendmail] MTA is not installed, the following link is used to
point to the [exim] binary. Due to this link, [ exim ] can be started
using the method of starting [sendmail].
$ file /usr/lib/sendmail
Output->
Start exim using the above link.
# /usr/lib/sendmail -q1h10m
It is possible to communicate with MTA directly, using raw SMTP
commands, over a telnet session to Port 25. Port 25 is assigned to
SMTP. You may check [/etc/services].
Sending mail using raw SMTP commands:
Initiate a telnet session on Port 25 of your host, to talk to MTA
using raw SMTP commands.
$ telnet 172.16.2.145 25
Replace 172.16.2.145 with Ethernet interface of your machine.
A portion of typical screen output for this example is shown below.
The texts without a leading number are commands executed by you. The
MTAs at the two ends use these leading numbers for communication.
Examples:
220 is the greeting message.
500 is one error message
$ telnet 172.16.2.146 25
Trying 172.16.2.146...
Connected to 172.16.2.146.
Escape character is '^]'.
220 cc-146.cc.cemk.ac.in ESMTP Exim 3.35 #1 Mon, 17 Mar 2006 18:32:13
+0530
ehlo cc.cemk.ac.in
250-cc-146.cc.cemk.ac.in Hello sumit at cc.cemk.ac.in [172.16.2.146]
250-SIZE
250-PIPELINING
250 HELP
help
214-Commands supported:
214- HELO EHLO MAIL RCPT DATA AUTH
214 NOOP QUIT RSET HELP
mail from: sumit@cc-146
250
rcpt to: guest@cc-146
250
data
354 Enter message, ending with "." on a line by itself
This is test mail... sumit
.
250 OK id=1FKb9W-0000KY-00
quit
221 cc-146.cc.cemk.ac.in closing connection
Connection closed by foreign host.
Check the mail of [guest].
# mail -u guest
Send a mail to a friend in another host using SMTP commands.
Was it successful ? ( Y / n )
Mail aliases:
User [ sumit ] wants to receive mail as [ sumit ], [ sumitbasu ],
[ sumit-basu ] and [ sumit_basu ]. This can be done with the help of
aliasing.
Replace [ sumit ] with your-log-name.
Edit [/etc/mail/aliases] as under. Replace [sumit] with your-log-name.
#.. [/etc/mail/aliases] ...
sumitbasu: sumit
sumit-basu: sumit
sumit_basu: sumit
#.. [/etc/mail/aliases] ...
Build the alias database file from the alias text file. Typical screen
output is also shown.
# exim_dbmbuild /etc/aliases /etc/aliases.db
3 entries written
Verify the aliases users.
# /usr/sbin/exim -bv sumitbasu
sumit@cc-146.cc.cemk.ac.in verified
# /usr/sbin/exim -bv sumit-basu
sumit@cc-146.cc.cemk.ac.in verified
# /usr/sbin/exim -bv sumit_basu
sumit@cc-146.cc.cemk.ac.in verified
# /usr/sbin/exim -bv sumit
sumit@cc-146.cc.cemk.ac.in verified
Request a friend to send a mail to sumit_basu
$ mail sumit_basu@cc-146.cc.cemk.ac.in < /dev/null
Group mails:
The alias mechanism can be used to send mails to a group of users.
Edit [/etc/mail/aliases] as under
------- /etc/mail/aliases -------
sumitbasu: sumit
sumit-basu: sumit
sumit_basu: sumit
3year: :include:/etc/exim/3y
---------------------------------
Edit file [/etc/exim/3y] as under.
------ /etc/mail/3y ------
sumit@cc-140.cc.cemk.ac.in
sunil@cc-145.cc.cemk.ac.in
you@localhost
--------------------------
Build the alias database file from the alias text file.
# exim_dbmbuild /etc/aliases /etc/aliases.db
4 entries written
Check the user [3year]
# /usr/sbin/exim -bv 3year
Send a mail to the group...
$ mail -v 3year
Subject: Group Mail
Testing group mail
.
Cc:
Request the recipients to check their mails.
----------
PPP
Documents to read:
1. Manual of pppd
2. PPP-HOWTO
Square brackets are used to separate keywords, such as filenames,
programs names etc etc from lines of text. They have no other meaning.
The Point-to-Point Protocol (PPP) provides a method for transmitting
datagrams over serial point-to-point links.
A possible PPP link between two hosts is shown below.
________ _________ _________ ________
| | | | | | | |
| Host-A |-ttyN-| modem-A |..............| modem-B |-ttyN-| Host-B |
|________| |_________| |_________| |________|
| |
ethN ethN
| |
A - network B - network
Figure-1
The above figure shows how computer network can be established between
two hosts with a modem at each end, using PPP. This figure also shows
that a PPP link can be used to connect two distant computer networks.
The main disadvantage is the speed of the link which is limited by the
speed of the modems.
Create directory [ppp] in your home directory.
$ mkdir $HOME/ppp
Carry out this experiment in that directory
$ cd $HOME/ppp
Bring
[ppp-681.txt] and
ppp_2.4.1.uus-4_i386.deb
in that directory. The actual package version number or name might
differ.
List the PPP related packages installed in your host.
$ dpkg -l | grep ppp
Replace the existing [pppd] or install [pppd].
# dpkg -i ppp_2.4.1.uus-4_i386.deb
From Figure-1 it is observed that a modem is to be connected to each
host. As a result, many modems are needed for one laboratory class. If
that many modems are not available, a simple PPP link over a short
distance can be established, using null modem ( cross-over cable )
between two hosts.
The following arrangement is to be used in this laboratory experiment.
______________________ ________________________
| | | |
| RxD Receive Data | 2 <--------- 3 | TxD Transmit Data |
| TxD Transmit Data | 3 ---------> 2 | RxD Receive Data |
| GND Signal Ground | 5 ---------- 5 | GND Signal Ground |
|______________________| |________________________|
| null-modem
| Host-1 Host-2
|
LAN
Figure-2
Host-1 is connected to laboratory LAN. Host-2 is kept disconnected
from the laboratory LAN. When PPP link is established between Host-1
and Host-2, Host-2 should be able to access other hosts of the LAN.
Hosts of the LAN should be able to access Host-2.
Figure-2 is redrawn to show the IP addresses associated with different
interfaces. Complete the addresses with pencil.
________ ________
| | 10.0.0.1(ppp0) 172.16.1.____(ppp0)| |
| Host-1 |------------------- null-modem -------------------| Host-2 |
|________| |________|
|172.16.1.____(eth0)
|
|
LAN ( 172.16.1.0 )
Figure-3
Record the IP address of eth0 interface of Host-2.
Host-2 # ifconfig
IP address of eth0 interface of Host-2---> ____________________
Use this address as the IP address of [ppp0] interface of Host-2. Use
pencil to write the address in Figure-3. We can use this address for
[ ppp0 ] interface, as eth0 interface of Host-2 is to be disabled in
this experiment.
Write the IP address of eth0 interface of Host-1 in Figure-3, using
pencil.
The eth0 interface of Host-2 is disabled
Host-2 # ifconfig eth0 down
Verify the effect of above command
Host-2 # ifconfig
The output should show loopback interface only. Host-2 is now
effectively disconnected from LAN. If Host-2 is rebooted, the command
# ifconfig eth0 down
must be executed again, for this experiment.
[ /etc/ppp/options ] is the configuration file for PPP daemon. PPP
daemon (pppd) is to be run on both Host-1 and Host-2.
The configuration file of [pppd] for Host-1 is shown below. The local-
IP-address of the PPP link is 10.0.0.1 . The far end of the PPP link
would supply the peer-IP-address, during the establishment of the PPP
link. It is assumed that null modem is using serial port [ttyS0].
-------- /etc/ppp/options --------
# configuration file for Host-1
/dev/ttyS0
57600
lock
debug
mru 296
# local-IP-address:peer-IP-address
10.0.0.1:
netmask 255.255.255.255
local # null modem is used
proxyarp
passive
----------------------------------
The configuration file of [pppd] for Host-2 is shown below. Write the
missing fourth octet of the local-IP-address of the PPP link. The far
end of the PPP link would supply the peer-IP-address, during the
establishment of the PPP link. In this experiment the peer-IP-address
would be 10.0.0.1 . It is assumed that null modem is using serial port
[ttyS0].
-------- /etc/ppp/options --------
# configuration file for Host-2
/dev/ttyS0
57600
lock
debug
mru 296
# local-IP-address:peer-IP-address
172.16.1.____:
netmask 255.255.255.255
local
----------------------------------
Find out the location of [pppd] binary executable file
Host-1/Host-2 # whereis -b pppd
location ------->
Check if [pppd] can access the options. Use full path-name if needed.
Host-1/Host-2 # pppd dryrun
Were the options printed ? ( Y / n )
If you are on Host-1, start [pppd].
Host-1 # pppd
In another terminal verify that [pppd] is running
$ ps ax | grep pppd
If you are on Host-2, start [pppd], while [pppd] is running in Host-1.
Host-2 # pppd
Use the following command and examine output
Host-1/Host-2 # tail -f /var/log/messages
Record the following:
Local IP address of PPP interface -------->
Remote IP address of the PPP interface --->
Try to access other hosts from Host-2. Use FTP, TELNET, PING etc etc.
Record the successful commands:
Try to access Host-2 from other hosts. Record the successful commands:
---------------------------
Optional Assignment:
In the above experiment, the commands were run
manually in the two hosts. The process may be automated if the
commands can be executed, at the later part of boot process. A shell
which runs the command, is executed, when a host boots.
Prepare the shell script.
Host-1/Host-2 $ nano $HOME/ppp/start-pppd
------------------- start-pppd -----------------------
#!/bin/bash
declare i x
while : # endless loop
do
x=$( /bin/pidof pppd )
if test -z $x # if value of x is a null string
then
echo "my-pppd: starting pppd"
/usr/sbin/pppd
elif test $x -gt 0 # PID value > zero
then
echo "my-pppd: pppd is running. PID = $x "
echo "my-pppd: sleeping for 5 minutes"
sleep 300
fi
done
# done > /tmp/myppd-debug
exit 0
------------------------------------------------------
The shell script starts [pppd], if [pppd] is not running. If [ pppd ]
is found running, it is checked at intervals of 5 minutes. The output
of the script would appears in Terminal-1. The reason for this is
explained later. This makes Terminal-1 unusable. The [ echo ] commands
may be commented, after the program is found to be working properly.
The output may also be redirected to a file, using the following
redirection in the script.
done > /tmp/myppd-debug
Make the file executable
Host-1/Host-2 $ chmod 0500 $HOME/ppp/start-pppd
Another shell script is prepared in [/etc/init.d] directory.
Host-1/Host-2 # nano /etc/init.d/my-pppd
------------ /etc/init.d/my-pppd --------------
#!/bin/bash
if test -x /home/your-login-name/ppp/start-pppd
then
/home/your-login-name/ppp/start-pppd &
fi
exit 0
-----------------------------------------------
Use actual path for the executable shell script [ start-pppd ]. The
above shell script checks the presence of the executable shell script
[ start-pppd ], in the specified path. If the test is successful, the
program [start-pppd] is started in background. Then [ my-pppd ] exits.
You must not omit the [&].
Make this program executable.
Host-1/Host-2 # chmod 0500 /etc/init.d/my-pppd
Create links to start the script in runlevels 2,3,4 and 5 (multiuser).
The following command may not be available in other Linux releases.
Host-1/Host-2 # update-rc.d my-pppd defaults
A possible output is shown:
Adding system startup for /etc/init.d/my-pppd ...
/etc/rc0.d/K20my-pppd -> ../init.d/my-pppd
/etc/rc1.d/K20my-pppd -> ../init.d/my-pppd
/etc/rc6.d/K20my-pppd -> ../init.d/my-pppd
/etc/rc2.d/S20my-pppd -> ../init.d/my-pppd
/etc/rc3.d/S20my-pppd -> ../init.d/my-pppd
/etc/rc4.d/S20my-pppd -> ../init.d/my-pppd
/etc/rc5.d/S20my-pppd -> ../init.d/my-pppd
At the end of the experiment, the links must be removed
Host-1/Host-2 # update-rc.d -f my-pppd remove
Reboot the two hosts in any order and check for establishment of PPP
link.
Did the PPP link come up ? ( Y / N )
If the PPP link does not come up, record the errors.
Errors:
---------------------
Note: PPP is widely used protocol. Most of dial-up computer networks
use this protocol. Many leased line computer networks use PPPoE
protocol. Many important aspects of PPP were skipped in this
experiment due to shortage of available time.
1. Manual of pppd
2. PPP-HOWTO
Square brackets are used to separate keywords, such as filenames,
programs names etc etc from lines of text. They have no other meaning.
The Point-to-Point Protocol (PPP) provides a method for transmitting
datagrams over serial point-to-point links.
A possible PPP link between two hosts is shown below.
________ _________ _________ ________
| | | | | | | |
| Host-A |-ttyN-| modem-A |..............| modem-B |-ttyN-| Host-B |
|________| |_________| |_________| |________|
| |
ethN ethN
| |
A - network B - network
Figure-1
The above figure shows how computer network can be established between
two hosts with a modem at each end, using PPP. This figure also shows
that a PPP link can be used to connect two distant computer networks.
The main disadvantage is the speed of the link which is limited by the
speed of the modems.
Create directory [ppp] in your home directory.
$ mkdir $HOME/ppp
Carry out this experiment in that directory
$ cd $HOME/ppp
Bring
[ppp-681.txt] and
ppp_2.4.1.uus-4_i386.deb
in that directory. The actual package version number or name might
differ.
List the PPP related packages installed in your host.
$ dpkg -l | grep ppp
Replace the existing [pppd] or install [pppd].
# dpkg -i ppp_2.4.1.uus-4_i386.deb
From Figure-1 it is observed that a modem is to be connected to each
host. As a result, many modems are needed for one laboratory class. If
that many modems are not available, a simple PPP link over a short
distance can be established, using null modem ( cross-over cable )
between two hosts.
The following arrangement is to be used in this laboratory experiment.
______________________ ________________________
| | | |
| RxD Receive Data | 2 <--------- 3 | TxD Transmit Data |
| TxD Transmit Data | 3 ---------> 2 | RxD Receive Data |
| GND Signal Ground | 5 ---------- 5 | GND Signal Ground |
|______________________| |________________________|
| null-modem
| Host-1 Host-2
|
LAN
Figure-2
Host-1 is connected to laboratory LAN. Host-2 is kept disconnected
from the laboratory LAN. When PPP link is established between Host-1
and Host-2, Host-2 should be able to access other hosts of the LAN.
Hosts of the LAN should be able to access Host-2.
Figure-2 is redrawn to show the IP addresses associated with different
interfaces. Complete the addresses with pencil.
________ ________
| | 10.0.0.1(ppp0) 172.16.1.____(ppp0)| |
| Host-1 |------------------- null-modem -------------------| Host-2 |
|________| |________|
|172.16.1.____(eth0)
|
|
LAN ( 172.16.1.0 )
Figure-3
Record the IP address of eth0 interface of Host-2.
Host-2 # ifconfig
IP address of eth0 interface of Host-2---> ____________________
Use this address as the IP address of [ppp0] interface of Host-2. Use
pencil to write the address in Figure-3. We can use this address for
[ ppp0 ] interface, as eth0 interface of Host-2 is to be disabled in
this experiment.
Write the IP address of eth0 interface of Host-1 in Figure-3, using
pencil.
The eth0 interface of Host-2 is disabled
Host-2 # ifconfig eth0 down
Verify the effect of above command
Host-2 # ifconfig
The output should show loopback interface only. Host-2 is now
effectively disconnected from LAN. If Host-2 is rebooted, the command
# ifconfig eth0 down
must be executed again, for this experiment.
[ /etc/ppp/options ] is the configuration file for PPP daemon. PPP
daemon (pppd) is to be run on both Host-1 and Host-2.
The configuration file of [pppd] for Host-1 is shown below. The local-
IP-address of the PPP link is 10.0.0.1 . The far end of the PPP link
would supply the peer-IP-address, during the establishment of the PPP
link. It is assumed that null modem is using serial port [ttyS0].
-------- /etc/ppp/options --------
# configuration file for Host-1
/dev/ttyS0
57600
lock
debug
mru 296
# local-IP-address:peer-IP-address
10.0.0.1:
netmask 255.255.255.255
local # null modem is used
proxyarp
passive
----------------------------------
The configuration file of [pppd] for Host-2 is shown below. Write the
missing fourth octet of the local-IP-address of the PPP link. The far
end of the PPP link would supply the peer-IP-address, during the
establishment of the PPP link. In this experiment the peer-IP-address
would be 10.0.0.1 . It is assumed that null modem is using serial port
[ttyS0].
-------- /etc/ppp/options --------
# configuration file for Host-2
/dev/ttyS0
57600
lock
debug
mru 296
# local-IP-address:peer-IP-address
172.16.1.____:
netmask 255.255.255.255
local
----------------------------------
Find out the location of [pppd] binary executable file
Host-1/Host-2 # whereis -b pppd
location ------->
Check if [pppd] can access the options. Use full path-name if needed.
Host-1/Host-2 # pppd dryrun
Were the options printed ? ( Y / n )
If you are on Host-1, start [pppd].
Host-1 # pppd
In another terminal verify that [pppd] is running
$ ps ax | grep pppd
If you are on Host-2, start [pppd], while [pppd] is running in Host-1.
Host-2 # pppd
Use the following command and examine output
Host-1/Host-2 # tail -f /var/log/messages
Record the following:
Local IP address of PPP interface -------->
Remote IP address of the PPP interface --->
Try to access other hosts from Host-2. Use FTP, TELNET, PING etc etc.
Record the successful commands:
Try to access Host-2 from other hosts. Record the successful commands:
---------------------------
Optional Assignment:
In the above experiment, the commands were run
manually in the two hosts. The process may be automated if the
commands can be executed, at the later part of boot process. A shell
which runs the command, is executed, when a host boots.
Prepare the shell script.
Host-1/Host-2 $ nano $HOME/ppp/start-pppd
------------------- start-pppd -----------------------
#!/bin/bash
declare i x
while : # endless loop
do
x=$( /bin/pidof pppd )
if test -z $x # if value of x is a null string
then
echo "my-pppd: starting pppd"
/usr/sbin/pppd
elif test $x -gt 0 # PID value > zero
then
echo "my-pppd: pppd is running. PID = $x "
echo "my-pppd: sleeping for 5 minutes"
sleep 300
fi
done
# done > /tmp/myppd-debug
exit 0
------------------------------------------------------
The shell script starts [pppd], if [pppd] is not running. If [ pppd ]
is found running, it is checked at intervals of 5 minutes. The output
of the script would appears in Terminal-1. The reason for this is
explained later. This makes Terminal-1 unusable. The [ echo ] commands
may be commented, after the program is found to be working properly.
The output may also be redirected to a file, using the following
redirection in the script.
done > /tmp/myppd-debug
Make the file executable
Host-1/Host-2 $ chmod 0500 $HOME/ppp/start-pppd
Another shell script is prepared in [/etc/init.d] directory.
Host-1/Host-2 # nano /etc/init.d/my-pppd
------------ /etc/init.d/my-pppd --------------
#!/bin/bash
if test -x /home/your-login-name/ppp/start-pppd
then
/home/your-login-name/ppp/start-pppd &
fi
exit 0
-----------------------------------------------
Use actual path for the executable shell script [ start-pppd ]. The
above shell script checks the presence of the executable shell script
[ start-pppd ], in the specified path. If the test is successful, the
program [start-pppd] is started in background. Then [ my-pppd ] exits.
You must not omit the [&].
Make this program executable.
Host-1/Host-2 # chmod 0500 /etc/init.d/my-pppd
Create links to start the script in runlevels 2,3,4 and 5 (multiuser).
The following command may not be available in other Linux releases.
Host-1/Host-2 # update-rc.d my-pppd defaults
A possible output is shown:
Adding system startup for /etc/init.d/my-pppd ...
/etc/rc0.d/K20my-pppd -> ../init.d/my-pppd
/etc/rc1.d/K20my-pppd -> ../init.d/my-pppd
/etc/rc6.d/K20my-pppd -> ../init.d/my-pppd
/etc/rc2.d/S20my-pppd -> ../init.d/my-pppd
/etc/rc3.d/S20my-pppd -> ../init.d/my-pppd
/etc/rc4.d/S20my-pppd -> ../init.d/my-pppd
/etc/rc5.d/S20my-pppd -> ../init.d/my-pppd
At the end of the experiment, the links must be removed
Host-1/Host-2 # update-rc.d -f my-pppd remove
Reboot the two hosts in any order and check for establishment of PPP
link.
Did the PPP link come up ? ( Y / N )
If the PPP link does not come up, record the errors.
Errors:
---------------------
Note: PPP is widely used protocol. Most of dial-up computer networks
use this protocol. Many leased line computer networks use PPPoE
protocol. Many important aspects of PPP were skipped in this
experiment due to shortage of available time.
NFS
Square brackets are used to separate keywords, such as filenames,
programs names etc, from lines of text. They have no other meaning.
NFS - Network File System : NFS service running in the local machine
provides distributed directory access and allows users of remote hosts
to mount file system of the local machine. To the remote user, the
mounted file system act and appear as if they are local. The file
system is made available by the local machine to the users of remote
machine by exporting the file system. The manner in which the files
are exported and their access, is controlled by entries in the file
[/etc/exports].
The following daemons are needed to provide NFS service.
rpc.portmap - When an RPC ( Remote Procedure Call ) server is started
( such as rpc.nfsd ), it will tell [portmap] what port
number it is listening to, and what RPC program numbers
it is prepared to serve. When a client wishes to make
an RPC call to a given program number, it will first
contact [ portmap ] on the server machine to determine
the port number where RPC packets should be sent.
[portmap] listens on Port-111( TCP/UDP )
rpc.mountd - It is a RPC server that answers a client request to
mount/unmount a file system in the server.
rpc.nfsd - This is the NFS server daemon.
rpc.lockd - This program starts the NFS lock manager ( NLM ) on
kernels that don't start it automatically. Most kernels
start it automatically. Moreover recent [ rpc.nfsd ]
calls [rpc.lockd] on demand. [rpc.lockd] is usually not
required to be started. Even so, running it anyway is
harmless.
rpc.statd - This daemon is used by the NFS file locking service,
[ rpc.lockd ] to implement lock recovery when the NFS
server machine crashes and reboots.
rpc.rquotad - This RPC server returns quotas for a user of a local
file system which is mounted by a remote machine over
the NFS. This not essential for server configuration.
It is not used in this experiment.
Create a directory NFS in your home directory and do the assignments
in that directory.
Complete Assignment-1.
NFS Installation:
Remove previous installation of NFS, if any
# dpkg -r nfs-user-server
Bring the following package in your NFS directory.
Filenames --->
/pool/main/n/nfs-user-server/nfs-user-server_2.2beta47-12_i386.deb on
CD-2
NFS binary package is to be installed in Assignment-2.
Complete Assignment-2.
Mounting NFS file system from client machine:
In Assignment-3, the
localhost is used as the client machine.
The client machine must have support for [nfs] file system. The output
of the following command should contain the string [nfs].
$ cat /proc/filesystems | grep nfs
output --> nodev nfs
The NFS file system on the server can be mounted in the client machine
by [mount] command directly or by an entry in the [ /etc/fstab ] file.
In Assignment-3, mounting is done with [mount] command. This command
need superuser privilege.
Complete Assignment-3.
In Assignment-4, mounting is done with help of an entry in the file
[/etc/fstab].
Complete Assignment-4.
Read manual [nfs(5)] to see the syntax of [fstab] entry for NFS.
You may read manual [mount(8)].
Read NFS-HOWTO, section 6, for security issues involved.
In Assignment-5, another machine in your LAN is used as the client
machine.
Complete Assignment-5.
-------------------------------------------
Assignment-1:
Find out whether [portmap] program is running.
$ ps ax | grep portmap
Is portmap running ? ( Y / N )
Is mountd running ? ( Y / N )
Is nfsd running ? ( Y / N )
Is statd running ? ( Y / N )
Is lockd running ? ( Y / N )
Is rquotad running ? ( Y / N )
Note: If [/etc/exports] file is empty, [nfsd] does not start.
Ask the [ portmapper ] running on localhost, by using the following
command, to print a list of all registered RPC programs and study the
output. You need not record the output.
$ rpcinfo -p localhost
Assignment-2.
Install [nfs-user-serve] and record the screen output.
# dpkg -i nfs-user-server_2.2beta47-12_i386.deb
Examine the output of this command. You need not record it.
# dpkg --status nfs-user-server
Edit [/etc/exports] to contain the following line
#......./etc/exports.........
/tmp *(rw,insecure)
#............................
The directory tree [/tmp] is exported.
[*] - Host wildcard. It indicates that [ /tmp ] in the server
machine can be exported to any host.
[rw] - Means that [ /tmp ] has read and write access. This is a
very loose permission used for illustration only.
[insecure] - This option allows client request to originate from an
Internet port less 1024.
Read manual [exports(5)] other options.
Start [nfsd]. Typical output is shown
# /etc/init.d/nfs-user-server restart
Stopping NFS servers: mountd nfsd.
Starting NFS servers: nfsd mountd.
Typical output of the following command is shown
$ rpcinfo -p localhost
program vers proto port
100000 2 tcp 111 portmapper
100000 2 udp 111 portmapper
100021 1 udp 1027 nlockmgr
100021 3 udp 1027 nlockmgr
100003 2 udp 2049 nfs
100003 2 tcp 2049 nfs
100005 1 udp 793 mountd
100005 2 udp 793 mountd
100005 1 tcp 796 mountd
100005 2 tcp 796 mountd
Add the followimg line in [/etc/hosts.allow], in case the [rpc.satad]
uses [tcpd].
ALL: ALL
Assignment-3:
Login to your account. Descend into [ NFS ] directory.
you $ cd NFS
NFS $ mkdir ./remote-dir
Become [root] and mount the directory exported by NFS server(localhost
in this assignment).
# mount -t nfs localhost:/tmp ./remote-dir
Descend into [./remote-dir] and copy [/etc/passwd] in it
remote-dir $ cp /etc/passwd ./
Try to find difference in the directory trees [/tmp] and
[/home/you/NFS/remote-dir]
$ diff /tmp /home/sumit/NFS/remote-dir/
Was there any difference ? ( Y / N )
Record the [nfs] related line from the output of this command.
# mount
Unmount NFS file system
# umount ./remote-dir/
Check successful un-mounting with
# mount or $ mount
Assignment-4:
Save the existing [/etc/fstab] file before making changes
# cp /etc/fstab /etc/fstab.org
Make a mount point in the client machine(localhost in this assignment)
# mkdir /nfs-mount-point
Add the following line in [/etc/fstab] in client machine ( localhost)
127.0.0.1:/tmp /nfs-mount-point nfs rw,user
[127.0.0.1:/tmp] - This field indicates the IP address of the NFS
server and the directory tree that is exported by
the server. [ localhost ] is the server in this
example.
The [mount] command can now be used by an ordinary user of client host
to mount the NFS directory.
$ mount /nfs-mount-point/
Record the output of the following command.
$ mount | grep nfs
Change permission of the previously copied file.
$ chmod 0007 /nfs-mount-point/passwd
Unmount NFS file system
$ umount /nfs-mount-point
Check un-mounting
$ mount
Assignment-5:
Note down the IP address of another machine to be used as
the client machine.
Your machine(192.168.10.10) is the NFS server.
In the NFS server do the following.
Create a directory [/public]. Create a subdirectory [sumit] in it.
# mkdir /public
# mkdir /public/sumit
Copy some files in the directories.
# cp /etc/passwd /public/
# cp /etc/hosts /public/
# cp /etc/hosts.allow /public/sumit/
Enter the following line in [/etc/exports] of NFS server.
#.............. /etc/exports of server ........
/public/ 192.168.10.9(rw,sync,all-sqush)
/public/sumit/ 192.168.10.10(noaccess)
#..............................................
Replace [192.168.10.9] with the IP address of client machine.
[/public/] can be mounted from client host [192.168.10.9] but
[/public/sumit/] would be inaccessible.
Restart the server
# /etc/init.d/nfs-user-server restart
Client machine:
Request the [ root ] user of the client machine to create a directory
[/nfs-tmp].
Request the [root] user of client machine to add the following entry
in [ /etc/fsatb ] of that machine.
192.168.10.10:/public /nfs-tmp nfs rw,user
As any user in the client machine, mount the NFS file system
tom $ mount /nfs-tmp
As user [tom] do the following.
$ cd /nfs-tmp/
$ cp /etc/passwd ./
$ chmod 0700 ./passwd
$ cd sumit
Try to see the files of the [sumit] directory.
Can the files be seen, except [. and .. ] ? ( Y / N )
Unmount NFS file system
$ umount /nfs-tmp
Request the [root] user of the client machine to remove the entry from
[/etc/fstab] and delete the directory [/nfs-tmp].
In the server machine restore the original [/etc/fstab] file.
Optional Assignment:
Download [nfs-kernel-server] source code,compile
and install NFS service.Install access control with [tcpd].
Test access from client machine using both UDP and TCP.
programs names etc, from lines of text. They have no other meaning.
NFS - Network File System : NFS service running in the local machine
provides distributed directory access and allows users of remote hosts
to mount file system of the local machine. To the remote user, the
mounted file system act and appear as if they are local. The file
system is made available by the local machine to the users of remote
machine by exporting the file system. The manner in which the files
are exported and their access, is controlled by entries in the file
[/etc/exports].
The following daemons are needed to provide NFS service.
rpc.portmap - When an RPC ( Remote Procedure Call ) server is started
( such as rpc.nfsd ), it will tell [portmap] what port
number it is listening to, and what RPC program numbers
it is prepared to serve. When a client wishes to make
an RPC call to a given program number, it will first
contact [ portmap ] on the server machine to determine
the port number where RPC packets should be sent.
[portmap] listens on Port-111( TCP/UDP )
rpc.mountd - It is a RPC server that answers a client request to
mount/unmount a file system in the server.
rpc.nfsd - This is the NFS server daemon.
rpc.lockd - This program starts the NFS lock manager ( NLM ) on
kernels that don't start it automatically. Most kernels
start it automatically. Moreover recent [ rpc.nfsd ]
calls [rpc.lockd] on demand. [rpc.lockd] is usually not
required to be started. Even so, running it anyway is
harmless.
rpc.statd - This daemon is used by the NFS file locking service,
[ rpc.lockd ] to implement lock recovery when the NFS
server machine crashes and reboots.
rpc.rquotad - This RPC server returns quotas for a user of a local
file system which is mounted by a remote machine over
the NFS. This not essential for server configuration.
It is not used in this experiment.
Create a directory NFS in your home directory and do the assignments
in that directory.
Complete Assignment-1.
NFS Installation:
Remove previous installation of NFS, if any
# dpkg -r nfs-user-server
Bring the following package in your NFS directory.
Filenames --->
/pool/main/n/nfs-user-server/nfs-user-server_2.2beta47-12_i386.deb on
CD-2
NFS binary package is to be installed in Assignment-2.
Complete Assignment-2.
Mounting NFS file system from client machine:
In Assignment-3, the
localhost is used as the client machine.
The client machine must have support for [nfs] file system. The output
of the following command should contain the string [nfs].
$ cat /proc/filesystems | grep nfs
output --> nodev nfs
The NFS file system on the server can be mounted in the client machine
by [mount] command directly or by an entry in the [ /etc/fstab ] file.
In Assignment-3, mounting is done with [mount] command. This command
need superuser privilege.
Complete Assignment-3.
In Assignment-4, mounting is done with help of an entry in the file
[/etc/fstab].
Complete Assignment-4.
Read manual [nfs(5)] to see the syntax of [fstab] entry for NFS.
You may read manual [mount(8)].
Read NFS-HOWTO, section 6, for security issues involved.
In Assignment-5, another machine in your LAN is used as the client
machine.
Complete Assignment-5.
-------------------------------------------
Assignment-1:
Find out whether [portmap] program is running.
$ ps ax | grep portmap
Is portmap running ? ( Y / N )
Is mountd running ? ( Y / N )
Is nfsd running ? ( Y / N )
Is statd running ? ( Y / N )
Is lockd running ? ( Y / N )
Is rquotad running ? ( Y / N )
Note: If [/etc/exports] file is empty, [nfsd] does not start.
Ask the [ portmapper ] running on localhost, by using the following
command, to print a list of all registered RPC programs and study the
output. You need not record the output.
$ rpcinfo -p localhost
Assignment-2.
Install [nfs-user-serve] and record the screen output.
# dpkg -i nfs-user-server_2.2beta47-12_i386.deb
Examine the output of this command. You need not record it.
# dpkg --status nfs-user-server
Edit [/etc/exports] to contain the following line
#......./etc/exports.........
/tmp *(rw,insecure)
#............................
The directory tree [/tmp] is exported.
[*] - Host wildcard. It indicates that [ /tmp ] in the server
machine can be exported to any host.
[rw] - Means that [ /tmp ] has read and write access. This is a
very loose permission used for illustration only.
[insecure] - This option allows client request to originate from an
Internet port less 1024.
Read manual [exports(5)] other options.
Start [nfsd]. Typical output is shown
# /etc/init.d/nfs-user-server restart
Stopping NFS servers: mountd nfsd.
Starting NFS servers: nfsd mountd.
Typical output of the following command is shown
$ rpcinfo -p localhost
program vers proto port
100000 2 tcp 111 portmapper
100000 2 udp 111 portmapper
100021 1 udp 1027 nlockmgr
100021 3 udp 1027 nlockmgr
100003 2 udp 2049 nfs
100003 2 tcp 2049 nfs
100005 1 udp 793 mountd
100005 2 udp 793 mountd
100005 1 tcp 796 mountd
100005 2 tcp 796 mountd
Add the followimg line in [/etc/hosts.allow], in case the [rpc.satad]
uses [tcpd].
ALL: ALL
Assignment-3:
Login to your account. Descend into [ NFS ] directory.
you $ cd NFS
NFS $ mkdir ./remote-dir
Become [root] and mount the directory exported by NFS server(localhost
in this assignment).
# mount -t nfs localhost:/tmp ./remote-dir
Descend into [./remote-dir] and copy [/etc/passwd] in it
remote-dir $ cp /etc/passwd ./
Try to find difference in the directory trees [/tmp] and
[/home/you/NFS/remote-dir]
$ diff /tmp /home/sumit/NFS/remote-dir/
Was there any difference ? ( Y / N )
Record the [nfs] related line from the output of this command.
# mount
Unmount NFS file system
# umount ./remote-dir/
Check successful un-mounting with
# mount or $ mount
Assignment-4:
Save the existing [/etc/fstab] file before making changes
# cp /etc/fstab /etc/fstab.org
Make a mount point in the client machine(localhost in this assignment)
# mkdir /nfs-mount-point
Add the following line in [/etc/fstab] in client machine ( localhost)
127.0.0.1:/tmp /nfs-mount-point nfs rw,user
[127.0.0.1:/tmp] - This field indicates the IP address of the NFS
server and the directory tree that is exported by
the server. [ localhost ] is the server in this
example.
The [mount] command can now be used by an ordinary user of client host
to mount the NFS directory.
$ mount /nfs-mount-point/
Record the output of the following command.
$ mount | grep nfs
Change permission of the previously copied file.
$ chmod 0007 /nfs-mount-point/passwd
Unmount NFS file system
$ umount /nfs-mount-point
Check un-mounting
$ mount
Assignment-5:
Note down the IP address of another machine to be used as
the client machine.
Your machine(192.168.10.10) is the NFS server.
In the NFS server do the following.
Create a directory [/public]. Create a subdirectory [sumit] in it.
# mkdir /public
# mkdir /public/sumit
Copy some files in the directories.
# cp /etc/passwd /public/
# cp /etc/hosts /public/
# cp /etc/hosts.allow /public/sumit/
Enter the following line in [/etc/exports] of NFS server.
#.............. /etc/exports of server ........
/public/ 192.168.10.9(rw,sync,all-sqush)
/public/sumit/ 192.168.10.10(noaccess)
#..............................................
Replace [192.168.10.9] with the IP address of client machine.
[/public/] can be mounted from client host [192.168.10.9] but
[/public/sumit/] would be inaccessible.
Restart the server
# /etc/init.d/nfs-user-server restart
Client machine:
Request the [ root ] user of the client machine to create a directory
[/nfs-tmp].
Request the [root] user of client machine to add the following entry
in [ /etc/fsatb ] of that machine.
192.168.10.10:/public /nfs-tmp nfs rw,user
As any user in the client machine, mount the NFS file system
tom $ mount /nfs-tmp
As user [tom] do the following.
$ cd /nfs-tmp/
$ cp /etc/passwd ./
$ chmod 0700 ./passwd
$ cd sumit
Try to see the files of the [sumit] directory.
Can the files be seen, except [. and .. ] ? ( Y / N )
Unmount NFS file system
$ umount /nfs-tmp
Request the [root] user of the client machine to remove the entry from
[/etc/fstab] and delete the directory [/nfs-tmp].
In the server machine restore the original [/etc/fstab] file.
Optional Assignment:
Download [nfs-kernel-server] source code,compile
and install NFS service.Install access control with [tcpd].
Test access from client machine using both UDP and TCP.
Subscribe to:
Posts (Atom)
