Having invested in a Linksys NSLU2 recently, I set myself the challenge of running as many of my network services as possible via the inetd supserserver to keep all my network services unloaded when they’re not needed (it only has 32MB of RAM after all). I probably went further than necessary really, just for the challenge.

inetd-based services already available that I used included:

  • SSH (dropbear)
  • Telnet (netkit)
  • FTP (openbsd)
  • OpenVPN
  • POP3 (popa3d)
  • IMAP4 (uw-imapd)

This left me having to write my own inetd servers to handle the following protocols. Well, I didn’t have to, but it was a fun problem and I really enjoy seeing a ps listing that contains just inetd, cron and the syslogger (yes, I’m weird).

  • DHCP
  • DNS
  • WWW
  • HTTP Proxy
  • SMTP
  • Jabber/XMPP
  • MVP Broadcast Relay
  • CTCS (CTorrent Control Server)

The great thing about these apps is that they’re simple, they’re all written in C, they don’t have any dependencies except the platform C library and none of their binaries are more than 20Kb in size (and well under 100Kb when running). I use them constantly and they simply don’t break - they follow the mantra of “do one thing and do it well”. I’ve only tested them against Linux since that’s what my machines run, but they shouldn’t require much (if any) work to port for other Unixes. They are ideal candidates for embedded platforms where other servers are simply too resource hungry.

Download on github


in.www is a tiny webserver that is designed to run through inetd. Support is limited to HTTP 1.0 and CGI 1.0


in.www is secure as possible. The default compile uses -DNORELATIVE, which causes 403 errors to be sent to any client attempting to use relative paths to escape the document tree. This stops 99% of web-based attacks. All buffers are carefully checked and limited in an attempt to prevent buffer overrun attacks.

The -DCGI compile switch enables CGI functionality. For a script to run, it can be anywhere in the tree (in.www does not have a cgi-bin directory) and must be executable. If you don’t need CGI and want the extra security, do not compile with this switch.

Other security features (allowed/disallowed hosts, spoof protection) are provided by the tcpd wrapper or xinetd depending on your choice. You can also chroot in.www if necessary (although it shouldn’t be). If you compiled with the -DONELOG switch, a log of requests in NCSA combined format will be output in /var/log/in.www.log

I use in.www on my slug to run my CGI playlist manager software and stream mp3 files to the mvpmc boxes around my house. Doing this takes just 0.3% of the slug’s CPU and 84Kb of RAM per stream.

See the README for compile/install instructions.


in.proxy is a tiny HTTP proxy. It supports all HTTP methods, does no caching and simply logs requests (if -DONELOG is enabled). It is intended as a simple HTTP relay for a network.

The CONNECT method is now supported, and in.proxy can be used as an SSL proxy. Security is handled via client filtering through tcpd/xinetd.

See the README for compile/install instructions.


in.jabberd is a tiny Jabber instant message server that is designed to run through inetd.


in.jabberd is simple to configure - /etc/in.jabberd.conf contains a list of usernames and their passwords. Mechanisms supported are plaintext passwords or SHA-1 digest authentication.

All users in the list are automatically each others buddies and basic presence notifications (online/offline) will be sent to users. This makes in.jabberd very useful for groups of people collaborating on a single server (moreso than the normal jabber daemons as you don’t have to mess around making each other buddies).

in.jabberd uses message files as outgoing transmit buffers for connected users, which are created in /tmp. To prevent unnecessary USB disk hammering on the slug, my /tmp directory is mounted as tmpfs - this should be the case for most Linux distributions anyway but it’s worth checking.

I use this as my local chat server to replace jabberd on my slug - it’s much simpler to set up, and it just works.

It’s probably also worth warning you that I’ve only really tested in.jabberd with the Pidgin and Gossip instant message clients, so your mileage may vary with other clients (Sep 2014, dummy support for privacy lists was added for compatibility with Empathy and others).

See the README file for installation instructions.


in.smtp is a tiny SMTP relay server designed to run through inetd. It will receive email via SMTP and then relay it by calling the system sendmail binary. This means you can use a small mailer (such as ssmtp for delivery out of your network. I use this to allow my NSLU2 to act as a mailhub for my local network.

in.smtp has no inherent security filtering, although with it being an inetd service, you can use the tcpd wrapper to restrict access to subnets and interfaces.

See the README file for installation instructions.


in.ctcs is an inetd-based version of the CTorrent Control Server, written in C.

It supports basic bandwidth sharing and download rate monitoring (under certain thresholds it will get more peers from the tracker or even completely reconnect.

A sample CGI web interface (for use with in.www or any CGI compliant webserver) is included to view downloading torrents, control them and download new torrents from pasted links. You’ll need a minimal python installation to run the web interface (it only uses the os, sys and datetime libs and obviously the python interpreter only runs when you are requesting a page) and wget for torrent link downloading.

See the README file for installation instructions.


in.dns is a miniscule DNS server designed to run through inetd. It only handles A and PTR records (which should be enough for a small network), is very easy to configure and like everything else on this page is written in C with no dependencies and is fast and small. It is deliberately aimed at small networks and low-powered hardware where the overhead of BIND is not needed.

It uses a single config file with a simple HOST -> ADDRESS format and infers PTR records from the first hostname for a given IP. You can also edit the config file without having to restart it.

in.dns is authoritative for the values in its config file (ie. It will give an answer for any fully qualified domain name you specify in the config file), but it does not do recursive searching (it will return a not found packet if it has no answer so that your client can move to the next server quickly).

This has now replaced BIND on my slug for handling DNS queries on my network.

In addition, if -DUSE_NSS is set, in.dns will act as a DNS relay for the local NSS. This allows you to use in.dns as a DNS relay on different subnets.

See the README file for installation instructions.


in.dhcp is a complete DHCP server designed to run through inetd. It handles ipv4, all standard DHCP options, multiple interfaces via xinetd, address pools, static leasing, and is fully compatible with the ISC DHCP, udhcp, Hauppage MVP H1+ and Wii clients (and anything you’d care to throw at it I expect, they’re just the ones I had handy to test with).

Configuring it is simple - a config file for each interface lists static lease parameters and global parameters are set at the bottom of the file (a sample config is included). A lease file for any dynamic pools on each interface is written to /tmp

Optionally, if -DUSE_NSS is set, in.dhcp will use /etc/ether and the local NSS to find hostnames and IP addresses for client MAC addresses.

See the README file for installation instructions and details on the config file format.


in.mvp is an inetd version of the mvprelay.c file floating around the net. I couldn’t track down the original author, but the source is given away freely.

It’s used to respond to the broadcast packets issued by later (H2+) revision Hauppage MVP devices - which they use to determine the TFTP server to get their OS from.

Older MVP revisions used the DHCP siaddr option and didn’t need a new protocol (and this relay program) to discover the TFTP server - but I guess not many non-nerds run their own DHCP server so Hauppage had to come up with a way for MVPs to get an address from any old device and then find their OS.

I modified it to work from inetd, threw away the win32 specific stuff (pah!), removed the unnecessary command line parameters and added improved logging via syslog.

Download on github