Exim

for the WRT

After having spent a lot of time trying to compile exim using uclibc, I gave up and compiled it on a real 'mipsel' system as a static binary, and after a few patches it worked ! You too, can now turn your WRT54 into a nice MTA.

The current binary is based on Exim 3.36 with added security patches and should run on any WRT firmware, (I use HyperWRT). All the files are here (sources, binaries, sample config).

To install Exim:

  1. Telnet your WRT, and transfer the files exim, exim.conf, domains, yourdomain.com to /tmp/exim
  2. Edit exim.conf and add your domains to 'local_domains', 'domains' in the 'userforward' section,
  3. Edit domains, to set the files which handle each virtual domain.
  4. Edit yourdomain.com files, to define all the virtual users and to which host the mail should be delivered. If the destination hostname cannot be resolved by the WRT, you should enclose the IP in square brackets.
  5. You should activate remote sysloging by launching something like 'syslogd -R 10.0.0.10:514'
  6. Start exim with './exim -bd -oX 25 -q15m' (add -d10 for debug mode)
  7. Unlock the port 25: '/usr/sbin/iptables -I INPUT -m tcp -p tcp --dport 25 -j ACCEPT'. Note that each time you reconfigure your WRT, the port 25 will be closed again.

You'll also find here the binary for OpenWRT routers (compiled with the toolchain mips_r2_gcc-4.6-linaro_uClibc-0.9.33.2). I used the same sources, and simply ran 'make CC=mips-openwrt-linux-gcc'. (mips arch, not mipsel)

My TODO list:

  • Remaining FS space is not working in the WRT, I had to disable the code which checks for enough free space in the spool.
  • Add a nice startup script.
  • Recompile with Debian patches.
  • Recompile with uclibc.
  • Run it with the spool on an external SD Card (SD card reader mod) to have plenty of space for the spool.
  • Download Exim after each WRT reboot.

Running kismet

You'll find some pre-compiled version of Kismet here that should run on the WRT54 family (which I found on http://gattaca.ru/~nikki/wrt54g/kismet.tar.bz2)

Then upload kismet_drone and kismet_drone.conf to your Linksys, and make sure you have the following line in your config file:

source=wrt54g,prism0,wrt54g

You now have to disable the AP mode of your router with a 'wl ap 0', and launch the following lines to see if you can find other APs:

wl scan 
wl scanresults

When you're ready, launch the drone, and your client.

./kismet_drone -f ./kismet_drone.conf (on the Linksys)
kismet -c kismet_drone,linksysip:3501,drone (on your PC)

With the binaries above, channels can not be set from the drone, and channel hoping does not seem to work. So I have the manually set the channel before launching the drone (with a 'wl channel 1' for example). If anyone has a binary that does not have this bug, please let me know.

Byte's nbench

I compiled the nbench for the Linksys (source and binaries here). I needed to patch the source since I found two bugs:

  1. clock() segfaults on the Linksys (?!). So I replaced clock() calls by times() calls.
  2. CLOCKS_PER_SEC has a bad value (1000000). So I replaced it by the real value: 100.

To run it you'll need the nbench binary but don't forget to upload also NNET.DAT. If you get interesting results, you can post them at http://www.tux.org/~mayer/linux/results2.html

You'll find below my results with Broadcom's gcc version 3.2.3 and '-O3 -fomit-frame-pointer' as optimization flags. So this 200Mhz MIPS CPU (Broadcom BCM9 4712) has roughly the power of a Pentium 100.

BYTEmark* Native Mode Benchmark ver. 2 (10/95)
Index-split by Andrew D. Balsa (11/97)
Linux/Unix* port by Uwe F. Mayer (12/96,11/97)

TEST                : Iterations/sec.  : Old Index   : New Index
                    :                  : Pentium 90* : AMD K6/233*
--------------------:------------------:-------------:------------
NUMERIC SORT        :          38.793  :       0.99  :       0.33
STRING SORT         :         0.92525  :       0.41  :       0.06
BITFIELD            :      1.0389e+07  :       1.78  :       0.37
FP EMULATION        :          5.7658  :       2.77  :       0.64
FOURIER             :          2.9669  :       0.00  :       0.00
ASSIGNMENT          :         0.45918  :       1.75  :       0.45
IDEA                :          186.63  :       2.85  :       0.85
HUFFMAN             :           9.086  :       0.25  :       0.08
NEURAL NET          :       0.0026126  :       0.00  :       0.00
LU DECOMPOSITION    :        0.076781  :       0.00  :       0.00
==========================ORIGINAL BYTEMARK RESULTS==========================
INTEGER INDEX       : 1.143
FLOATING-POINT INDEX: 0.004
Baseline (MSDOS*)   : Pentium* 90, 256 KB L2-cache, Watcom* compiler 10.0
==============================LINUX DATA BELOW===============================
**System used for compilation:
**Linux red 2.4.22-1-k6 #5 Sat Oct 4 14:38:05 EST 2003 i686 GNU/Linux
**C compiler: mipsel-uclibc-gcc (unknown version)
**CFLAGS : -O3 -fomit-frame-pointer
**libc: unknown version
**Date of compilation: Tue Dec 14 14:03:43 CET 2004
MEMORY INDEX        : 0.221
INTEGER INDEX       : 0.345
FLOATING-POINT INDEX: 0.002
Baseline (LINUX)    : AMD K6/233*, 512 KB L2-cache, gcc 2.7.2.3, libc-5.4.38
* Trademarks are property of their respective holder.

When compiled on a real 'mipsel' system, with gcc 3.3.5 and glibc 2.3.2, I get better results (30% faster):

BYTEmark* Native Mode Benchmark ver. 2 (10/95)
Index-split by Andrew D. Balsa (11/97)
Linux/Unix* port by Uwe F. Mayer (12/96,11/97)

TEST                : Iterations/sec.  : Old Index   : New Index
                    :                  : Pentium 90* : AMD K6/233*
--------------------:------------------:-------------:------------
NUMERIC SORT        :          42.988  :       1.10  :       0.36
STRING SORT         :          2.4715  :       1.10  :       0.17
BITFIELD            :      1.2569e+07  :       2.16  :       0.45
FP EMULATION        :          7.0395  :       3.38  :       0.78
FOURIER             :          2.4288  :       0.00  :       0.00
ASSIGNMENT          :         0.48765  :       1.86  :       0.48
IDEA                :          245.93  :       3.76  :       1.12
HUFFMAN             :          8.0802  :       0.22  :       0.07
NEURAL NET          :       0.0024404  :       0.00  :       0.00
LU DECOMPOSITION    :        0.065816  :       0.00  :       0.00
==========================ORIGINAL BYTEMARK RESULTS==========================
INTEGER INDEX       : 1.456
FLOATING-POINT INDEX: 0.003
Baseline (MSDOS*)   : Pentium* 90, 256 KB L2-cache, Watcom* compiler 10.0
==============================LINUX DATA BELOW===============================
CPU                 : 
L2 Cache            : 
OS                  : Linux 2.4.20
C compiler          : gcc version 3.3.5 (Debian 1:3.3.5-13)
libc                : ld-2.3.2.so
MEMORY INDEX        : 0.333
INTEGER INDEX       : 0.388
FLOATING-POINT INDEX: 0.002

Firewall Q/A

How ActiveX filtering is done ?

When you activate ActiveX filtering, you'll add an iptable rule like this

    0     0 REJECT     tcp  --  br0    vlan1   anywhere             anywhere
       tcp dpt:www WEBSTR match content 2 reject-with tcp-reset

The '2' comes from bits defined in a .h:

#define BLK_JAVA                0x01
#define BLK_ACTIVE              0x02
#define BLK_COOKIE              0x04
#define BLK_PROXY               0x08

So the filtering is done by a new kernel module 'ipt_webstr' (net/ipv4/netfilter/ipt_webstr.c in the Linksys kernel sources), and an iptables shared lib derived from the string match iptables module.

Running snmpd

You can find snmpd binaries and a sample snmpd.conf file here, but I can't remember who built these binaries... Once downloaded in the 'tmp' of the WRT, run

/tmp/snmpd -c /tmp/snmpd.conf           (the absolute path for the config file seems to be needed)

You should tweak snmpd.conf, because this sample file allows everything without authentication. On your PC, you can now check that everything works with snmpwalk:

snmpwalk -v 1 -c public gw

Misc utilities

In my software repository, you'll also find some small and useful utilities extracted from the OpenWRT distribution, and which work with HyperWRT:

  • bwm, a small bandwidth monitor
  • fping, an improved ping
  • iptraf, a nice bandwidth traffic monitor
  • strace, ...if you don't know what it is, you don't need it...

Projects not completed

NFS mount support

Kernel modules compiled fine and they can be inserted without problems on a Linksys running the HyperWRT firmware (download here). But now I need a mount command which can be used for NFS, I first tried to enable some features in busybox but I got this compilation error:

nfsmount.o(.text+0x25c0): 
  undefined reference to `xdr_opaque'

So I need to edit my uClibc Config and set INCLUDE_RPC=true...

Newbie Q/A

How can I get a shell ?
Install the HyperWRT distribution on it. You'll get telnet access.
How can I transfer files to my WRT ?
Use busybox's wget. You can't use the running tftpd server since it's a modified one which can only be used for firmware flashing.
How can I transfer WRT files to my PC?
Launch another http server: cd /tmp; httpd -p 8080. Caveats: you'll need to authenticate with your admin login, files need to end in .asp.