The first but secondary purpose of this
article is to introduce you this nifty networking tool:
/usr/bin/netcat
which is well available from the Debian
GNU/Linux under the package name netcat
. (The drill:
apt-get install netcat
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 hackish feeling,
think it, insists on and successful in being anonymous, after
written such an excellent piece of software. Only true Unix guru could
do that!
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 cat
program to forward data from stdin to
stdout. According to unconfirmed sources, that's the origin of the
netcat program name.
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!
So here we introduce the nutty yescat for a purpose which will
show itself later: /usr/bin/yes
. Nearly nobody even
noticed it. But it quietly lies there in a corner of
/usr/bin
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
/sbin/init
! What does it do? Lets' see for our own eyes:
zw@q ~ % yes y y y y y y y
Isn't it wonderful? ;-) (Press ctrl-C
to stop the y's, otherwise
they'll march down the screen forever.) It can even say no too!
zw@q ~ % yes no no no no no no
In the following sections we will develop two companion utilities
with which we will eventually reinvent /usr/bin/yes
with
the help from /usr/bin/netcat
of course! Lets' start the
journey now!
The hub (hub.c) and cable (cable.c) 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 multiplex 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! ;-)
zw@q ~ % ./hub lullaby internetworks lab: (server alike) hub $Revision: 1.2 $ Copyright (C) 2001 zhaoway <zw@debian.org> 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 ~ %
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.
ConA % ./hub 10240 10000 2
ConB % nc localhost 10000
ConC % nc localhost 10000
Then there is cable:
zw@q ~ % ./cable lullaby internetworks lab: (client alike) cable $Revision: 1.2 $ Copyright (C) 2001 zhaoway <zw@debian.org> 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 ~ %
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.
ConA % nc -l -p 10000
ConB % nc -l -p 10001
ConC % ./cable 10240 127.0.0.1 10000 127.0.0.1 10001
There are some interesting techniques used in developing hub and
cable. Notably the select()
function call. But for now,
we will focus on our course to reinvent the /usr/bin/yes
first. ;-)
It's not a very easy task to reinvent /usr/bin/yes
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!
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:
| cable \|/ ,---------, | | | V V V ,--[ ]-------[ ]-------[ ]--. | A B C | | three-port hub | `---------------------------'
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.
Lets' construct the device.
ConA % ./hub 10240 10000 3
ConB % ./cable 10240 127.0.0.1 10000 127.0.0.1 10000
Now after we finished construction of our device, then we will
using netcat to finally finish our reinvention of /usr/bin/yes
.
ConC % echo "y" | nc localhost 10000 y y y y y y
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.
Have fun and good luck!
zhaoway
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 Debian
GNU/Linux project.
Copyright © 2002, zhaoway.
Copying license http://www.linuxgazette.net/copying.html
Published in Issue 74 of Linux Gazette, January 2002