hubertf's NetBSD Blog
Send interesting links to hubert at feyrer dot de!
[20050801] Multiplexing TCP services: inetd's tcpmux (Updated)
Have you ever used inetd's built-in tcpmux service? Neither have I, but after someone asked about it on #NetBSD today, I thought to give it a try. After not understanding the manpage on first read, it seems it's a re-invention of rpcbind (or vice versa), where you can create a TCP connection to the tcpmux port (1/tcp), and ask for a connection to a service to which you get connected then, by only knowing a service name, no port number needed.

Here's an example:

 (a) --> miyu# egrep '^(tcpmux|ftp)' /etc/inetd.conf 
         ftp             stream  tcp     nowait  root    /usr/libexec/ftpd       ftpd -ll
         tcpmux          stream  tcp     nowait  root    internal
 (b) --> miyu# telnet localhost 1
         Connected to localhost.
         Escape character is '^]'.
 (c) --> ftp
 (d) --> -Service not available
         Connection closed by foreign host.
 (e) --> miyu# egrep ^ftp /etc/inetd.conf | sed 's,^,tcpmux/,' >>/etc/inetd.conf
 (f) --> miyu# egrep '^ftp' /etc/inetd.conf
         ftp             stream  tcp     nowait  root    /usr/libexec/ftpd       ftpd -ll
         tcpmux          stream  tcp     nowait  root    internal
         tcpmux/ftp      stream  tcp     nowait  root    /usr/libexec/ftpd       ftpd -ll
         miyu# alias hup 
         kill -1 `cat /var/run/!*.pid`
 (g) --> miyu# hup inetd
 (h) --> miyu# telnet localhost 1
         Connected to localhost.
         Escape character is '^]'.
 (i) --> ftp
 (j) --> 220-
         220 localhost FTP server (NetBSD-ftpd 20050303) ready.
 (k) --> ^]
         telnet> quit
         Connection closed.
The example first checks that the FTP and TCPMUX service are enabled in inetd.conf (a), then connects to the local tcpmux port (b) to ask for a connection to the "ftp" service (c), which is not available (d). Now after reading the inetd(8) manpage five times, duplicate the "ftp" line and prefix it with "tcpmux/" (e), and check that it got added to inetd.conf (f). Make sure that inetd reads in the changed config file (g). When connecting now (h) and asking for the "ftp" service (i), the ftp daemon is started and prints its banner (j).

As I don't really feel like speaking FTP without a client, I disconnect (k) and exit telnet.

So, the tcpmux service seems quite a nice tool which could be used to obsolete assigning ports in favour of service names. The problem is that no TCP service that I've stumbled across ever uses this nice mechanism. Even more strange, I wonder why things like rpcbind/portmap were invented in the presence of that serivce (and I guess that tcpmux does predate rpcbind etc.).

To play a bit more, I built myself a "cookie" service, adding this to /etc/inetd.conf:

tcpmux/cookie   stream  tcp     nowait  root    /usr/games/fortune fortune
Now I can run:
      miyu# echo cookie | nc localhost 1
      'Home, Sweet Home' must surely have been written by a bachelor.

Who needs port numbers when you can request a service like this easily. :-) After reading RFC 1078, I even found that the protocol could safe one portscanning a machine to find out the services it runs:

      miyu# echo HELP | nc localhost 1
      +Available services:

And for the problem of having multiple versions of the same service running (which rpcbind addresses), RFC 1078 has a suggestion, too: ``Multiple versions of a protocol can suffix the service name with a protocol version number. ''. Easy, huh?

Looking into portmap and friends, Appendix A of RFC 1047 says that ``The port mapper program maps RPC program and version numbers to transport-specific port numbers. This program makes dynamic binding of remote programs possible.''. I.e. reasons for existance of rpcbind etc. are that that rpcbind does which are not easily achievable with the inetd/tcpmux combination: dynamic registration of services, transport over UDP and handling of broadcast requests.

P.S.: Try running fortune(6) without argv[0] being set. :-)

Update: Aparently the tcpmux service is actualy being used by Irix 6.5. Martin Neitzel sent me the inetd.conf of such a machine:

 % grep tcpmux irix65_inetd.conf
 tcpmux  stream  tcp     nowait  root    internal
 tcpmux/sgi_scanner stream tcp nowait root   ?/usr/lib/scan/net/scannerd scannerd
 tcpmux/sgi_printer stream tcp nowait root   ?/usr/lib/print/printerd printerd
 tcpmux/sgi_sysadm stream tcp nowait root   ?/usr/sysadm/bin/sysadmd sysadmd
 tcpmux/sgi_dmusrcmd stream tcp nowait root ?/usr/etc/dmusrcmd /usr/etc/dmusrcmd 

[Tags: , ]

Disclaimer: All opinion expressed here is purely my own. No responsibility is taken for anything.

Access count: 34865191
Copyright (c) Hubert Feyrer