old-www/LDP/LG/issue74/zhaoway.html

279 lines
11 KiB
HTML

<!--startcut ==============================================-->
<!-- *** BEGIN HTML header *** -->
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 3.2//EN">
<HTML><HEAD>
<title>Play with the Lovely Netcat LG #74</title>
</HEAD>
<BODY BGCOLOR="#FFFFFF" TEXT="#000000" LINK="#0000FF" VLINK="#0000AF"
ALINK="#FF0000">
<!-- *** END HTML header *** -->
<CENTER>
<A HREF="http://www.linuxgazette.com/">
<IMG ALT="LINUX GAZETTE" SRC="../gx/lglogo.png"
WIDTH="600" HEIGHT="124" border="0"></A>
<BR>
<!-- *** BEGIN navbar *** -->
<IMG ALT="" SRC="../gx/navbar/left.jpg" WIDTH="14" HEIGHT="45" BORDER="0" ALIGN="bottom"><A HREF="tougher.html"><IMG ALT="[ Prev ]" SRC="../gx/navbar/prev.jpg" WIDTH="16" HEIGHT="45" BORDER="0" ALIGN="bottom"></A><A HREF="index.html"><IMG ALT="[ Table of Contents ]" SRC="../gx/navbar/toc.jpg" WIDTH="220" HEIGHT="45" BORDER="0" ALIGN="bottom" ></A><A HREF="../index.html"><IMG ALT="[ Front Page ]" SRC="../gx/navbar/frontpage.jpg" WIDTH="137" HEIGHT="45" BORDER="0" ALIGN="bottom"></A><A HREF="http://www.linuxgazette.com/cgi-bin/talkback/all.py?site=LG&article=http://www.linuxgazette.com/issue74/zhaoway.html"><IMG ALT="[ Talkback ]" SRC="../gx/navbar/talkback.jpg" WIDTH="121" HEIGHT="45" BORDER="0" ALIGN="bottom" ></A><A HREF="../faq/index.html"><IMG ALT="[ FAQ ]" SRC="./../gx/navbar/faq.jpg"WIDTH="62" HEIGHT="45" BORDER="0" ALIGN="bottom"></A><A HREF="lg_backpage.html"><IMG ALT="[ Next ]" SRC="../gx/navbar/next.jpg" WIDTH="15" HEIGHT="45" BORDER="0" ALIGN="bottom" ></A><IMG ALT="" SRC="../gx/navbar/right.jpg" WIDTH="15" HEIGHT="45" ALIGN="bottom">
<!-- *** END navbar *** -->
<P>
</CENTER>
<!--endcut ============================================================-->
<H4 ALIGN="center">
"Linux Gazette...<I>making Linux just a little more fun!</I>"
</H4>
<P> <HR> <P>
<!--===================================================================-->
<center>
<H1><font color="maroon">Play with the Lovely Netcat:<BR>
Reinvent /usr/bin/yes</font></H1>
<H4>By <a href="mailto:zw@debian.org">zhaoway</a></H4>
</center>
<P> <HR> <P>
<!-- END header -->
<h2>Netcat and Yescat</h2> <p> The first but secondary purpose of this
article is to introduce you this nifty networking tool:
<code>/usr/bin/netcat</code> which is well available from the Debian
GNU/Linux under the package name <code>netcat</code>. (The drill:
<code>apt-get install netcat</code> and you're done.) There are very
well written companion documentation by the anonymous software author,
and from which a well formatted Unix manual page by my fellow Debian
developers. Reading the companion documentation is really an
interesting experience. It would almost certainly reminds the gentle
reader that there is truly this kind of creature called Unix gurus
living somewhere at the large. That kind of <i>hackish</i> feeling,
think it, insists on and successful in being <i>anonymous</i>, after
written such an excellent piece of software. Only true Unix guru could
do that!
<p> Since the netcat documentation is of such excellent quality, I will
not duplicate it here. (However, I recommend you read the netcat
documentation before reading this article.)
For those of you with
little patience, netcat could forward data stream from stdin to a
TCP or UDP socket, and from a TCP or UDP socket to stdout. Just like
the <code>cat</code> program to forward data from stdin to
stdout. According to unconfirmed sources, that's the origin of the
netcat program name.
<p> The second but primary purpose of this article is to show you how
tedious and clueless an article author (like me) can be,
introducing a piece of software which does not
have any graphical user interface, or any interactive help system. Ya
know, I would simply go crazy if I cannot capture a screenshot or two!
<p> So here we introduce the nutty yescat for a purpose which will
show itself later: <code>/usr/bin/yes</code>. Nearly nobody even
noticed it. But it quietly lies there in a corner of
<code>/usr/bin</code> for so long that nearly none of us latecomers
to the Linux world ever noticed it in any of our Linux systems.
Its origin remains a mystery. Its popularity is just as
<code>/sbin/init</code>! What does it do? Lets' see for our own eyes:
<p>
<pre>
zw@q ~ % yes
y
y
y
y
y
y
y
</pre>
<p> Isn't it wonderful? ;-) (Press <CODE>ctrl-C</CODE> to stop the y's, otherwise
they'll march down the screen forever.) It can even say <i>no</i> too!
<p>
<pre>
zw@q ~ % yes no
no
no
no
no
no
</pre>
<p> In the following sections we will develop two companion utilities
with which we will eventually reinvent <code>/usr/bin/yes</code> with
the help from <code>/usr/bin/netcat</code> of course! Lets' start the
journey now!
<h2>Hub and cable</h2>
<p> The hub (<a href="misc/zhaoway/hub.c.txt">hub.c</a>) and cable (<a
href="misc/zhaoway/cable.c.txt">cable.c</a>) utilities are certainly
inspired by netcat which could forward data stream from a socket to
stdout, and from stdin to a socket. Did I forget to recommend the
netcat companion documentation for you to read? ;-) Hub is designed to
be like a server, and cable is designed to be like a client. Instead
of forwarding data between stdin/stdout and a socket, hub and cable
forward and <i>multiplex</i> data from a socket to any other
sockets. That's where the names come from. They're just like Ethernet
hub and cable. Lets' see a screenshot. Yeah, screenshot! ;-)
<p>
<pre>
zw@q ~ % ./hub
lullaby internetworks lab: (server alike) hub $Revision: 1.2 $
Copyright (C) 2001 zhaoway &lt;zw@debian.org&gt;
Usage: hub [hub buffer size] [tcp port number] [number of hub ports]
o hub buffer size is in bytes. for example 10240.
o tcp port number is at least 1024 so i do not need to be root.
o number of hub ports is at least 2. happy.
zw@q ~ %
</pre>
<p> Hub will listen on a TCP port simulating a many port Ethernet
hub. Data come in from one hub port will be forwarded to other hub
ports. You could test the hub alone without cable using netcat. Note:
nc is the acronym for netcat.
<ol>
<li>Launch hub in the console A: <code>ConA % ./hub 10240 10000 2</code>
<li>From console B, connect a netcat: <code>ConB % nc localhost 10000</code>
<li>From console C, connect another netcat: <code>ConC % nc localhost 10000</code>
<li>Then you could type in ConC and read the output in ConB, vice versa.
</ol>
<p> Then there is cable:
<p>
<pre>
zw@q ~ % ./cable
lullaby internetworks lab: (client alike) cable $Revision: 1.2 $
Copyright (C) 2001 zhaoway &lt;zw@debian.org&gt;
Usage: cable [cable buffer size] [1st ip] [1st port] [2nd ip] [2nd port] ..
o cable buffer size is in bytes. for example 10240.
o ports should be listening or connection attempts will fail.
o number of ip addr and port pairs is at least 2.
zw@q ~ %
</pre>
<p> Cable is more or less like a shared Ethernet bus coaxial cable. It
forwards and multiplexes data between listening socket daemons. Let's
test it too.
<ol>
<li>Launch a netcat daemon in ConA: <code>ConA % nc -l -p 10000</code>
<li>Launch another netcat daemon in ConB: <code>ConB % nc -l -p 10001</code>
<li>Arrange the cable: <code>ConC % ./cable 10240 127.0.0.1 10000 127.0.0.1 10001</code>
<li>Then you could type in ConA and read the output from ConB, vice versa.
</ol>
<p> There are some interesting techniques used in developing hub and
cable. Notably the <code>select()</code> function call. But for now,
we will focus on our course to reinvent the <code>/usr/bin/yes</code>
first. ;-)
<h2>Reinvent the wheel</h2>
<p> It's not a very easy task to reinvent <code>/usr/bin/yes</code>
using netcat and hub and cable. I could only give a cheat answer. And
that's why I need to set the buffer size command line argument. But
anyway, let's begin!
<p> The main idea is as following. First we set up a three-port hub,
then we using cable to connect two hub port together, after that we
could using netcat to echo any character into the remain free hub
port. It's like the following diagram:
<p>
<pre>
| cable
\|/ ,---------,
| | |
V V V
,--[ ]-------[ ]-------[ ]--.
| A B C |
| three-port hub |
`---------------------------'
</pre>
<p> Because the nature of the hub, data sent in from port A, will be
forwarded to port B and port C, since port B and C are connected by a
cable, the data come out of the hub will go right back in, and then
being multiplexed and forwarded to port A and circulating in the cable
loop to eternity. Eventually port A will receive infinite copies of the
original data sent in.
<p> Lets' construct the device.
<ol>
<li>In ConA, we launch the three-port hub: <code>ConA % ./hub 10240 10000 3</code>
<li>In ConB, we loop the cable: <code>ConB % ./cable 10240 127.0.0.1 10000 127.0.0.1 10000</code>
</ol>
<p> Now after we finished construction of our device, then we will
using netcat to finally finish our reinvention of <code>/usr/bin/yes</code>.
<p>
<pre>
ConC % echo "y" | nc localhost 10000
y
y
y
y
y
y
</pre>
<p> The tricky exercises left for the reader is: what if we change the
buffer size of both cable and hub from 10240 to 1? You could try and
see for yourself.
<p> Have fun and good luck!
<!-- *** BEGIN bio *** -->
<SPACER TYPE="vertical" SIZE="30">
<P> <H4><IMG ALIGN=BOTTOM ALT="" SRC="../gx/note.gif">zhaoway</H4>
<EM>zhaoway lives in Nanjing, China. He divides his time among his
beautiful girlfriend, his old Pentium computer, and pure
mathematics. He wants to marry now, which means he needs money, ie., a
job. Feel free to help him come into the sweet cage of marriage by
providing him a job opportunity. He would be very thankful! He is also
another volunteer member of the <a href="http://www.debian.org">Debian
GNU/Linux</a> project.</EM>
<!-- *** END bio *** -->
<!-- *** BEGIN copyright *** -->
<P> <hr> <!-- P -->
<H5 ALIGN=center>
Copyright &copy; 2002, zhaoway.<BR>
Copying license <A HREF="../copying.html">http://www.linuxgazette.com/copying.html</A><BR>
Published in Issue 74 of <i>Linux Gazette</i>, January 2002</H5>
<!-- *** END copyright *** -->
<!--startcut ==========================================================-->
<HR><P>
<CENTER>
<!-- *** BEGIN navbar *** -->
<IMG ALT="" SRC="../gx/navbar/left.jpg" WIDTH="14" HEIGHT="45" BORDER="0" ALIGN="bottom"><A HREF="tougher.html"><IMG ALT="[ Prev ]" SRC="../gx/navbar/prev.jpg" WIDTH="16" HEIGHT="45" BORDER="0" ALIGN="bottom"></A><A HREF="index.html"><IMG ALT="[ Table of Contents ]" SRC="../gx/navbar/toc.jpg" WIDTH="220" HEIGHT="45" BORDER="0" ALIGN="bottom" ></A><A HREF="../index.html"><IMG ALT="[ Front Page ]" SRC="../gx/navbar/frontpage.jpg" WIDTH="137" HEIGHT="45" BORDER="0" ALIGN="bottom"></A><A HREF="http://www.linuxgazette.com/cgi-bin/talkback/all.py?site=LG&article=http://www.linuxgazette.com/issue74/zhaoway.html"><IMG ALT="[ Talkback ]" SRC="../gx/navbar/talkback.jpg" WIDTH="121" HEIGHT="45" BORDER="0" ALIGN="bottom" ></A><A HREF="../faq/index.html"><IMG ALT="[ FAQ ]" SRC="./../gx/navbar/faq.jpg"WIDTH="62" HEIGHT="45" BORDER="0" ALIGN="bottom"></A><A HREF="lg_backpage.html"><IMG ALT="[ Next ]" SRC="../gx/navbar/next.jpg" WIDTH="15" HEIGHT="45" BORDER="0" ALIGN="bottom" ></A><IMG ALT="" SRC="../gx/navbar/right.jpg" WIDTH="15" HEIGHT="45" ALIGN="bottom">
<!-- *** END navbar *** -->
</CENTER>
</BODY></HTML>
<!--endcut ============================================================-->