Hacking Functionality into ASUSWRT Routers

This weekend, I spent some time to replace my aged Linksys WRT54G wireless router, which is running DD-WRT. The WRT54G is slow by today’s wireless standards and since I sync my iOS devices wirelessly, the speed was getting quite unbearable. When I bought my Macbook Pro in 2007, it already has draft 802.11n support and fast-forward to 2012, my iPad (1st generation) and iPhone 5 both support the 5GHz band.

The ASUS RT-N56U wireless router ranks up there on wireless performance, and the “feature” I was really after was a router that can run an alternative firmware such as Tomato or DD-WRT. The really good news is, I figured out how to get the functionality I wanted while still using the official ASUS firmware.

ASUS router photo

For proper reviews and better photos, you might want to check out these other reviews:

Read on to find my short review, as well as how you can run your own programs on the router without using a third-party firmware.

A Geek’s Review

It is a dual-band router, which means it operates on both the 2.4GHz and 5GHz frequency bands simultaneously. Its antennas are built-in (actually on the PCB) so you won’t be able to swap them for higher gain ones.

The router has no wall-mounting holes, unfortunately, but it has a flat back so it can be laid on a flat surface. It comes with a stand that you can use to prop it up and face in a particular direction, but I chose not attach it. There have been reports of instability due to heat build up, so I do not recommend that you stack it on top of other equipment. Use some type of spacer if you have to, for airflow.

It uses a “non-standard” small diameter barrel jack which accepts 19V @ 1.58A, so if you’re planning on using an alternative power supply, or a Power-over-Ethernet (POE) injector, you will have some work to do.

There are a few firmware alternatives available for the RT-N56U, but DD-WRT is not one of them. The most popular one seems to be Asuswrt-Merlin. There is another one that was posted on the DD-WRT forum: https://code.google.com/p/rt-n56u/

Actually, my requirements are quite simple. I just need a DHCP forwarder (which DD-WRT had) to forward requests to my main DHCP server and I need to be able to run mDNS Repeater to repeat mDNS packets between the wireless and wired subnets. It turns out that I could fulfill both of these requirements without installing an alternative firmware.

What is ASUSWRT?

ASUS created a unified firmware for their routers called ASUSWRT. The whole thing, including the userland, is open source (except for proprietary kernel modules from the chip manufacturer), which is really nice. I can’t find much information about which routers can be upgraded to ASUSWRT, but the newer routers such as RT-N66U, RT-N56U, and some older ones like RT-N16 are supported.

So how can you tell if your router supports ASUSWRT? ASUS doesn’t explicitly advertise this, but on the firmware download page for your router, the ASUSWRT firmware can be identified by having at least version 3.0.0.3.x and above, or there might be a hint of it in the description (as shown here):

screenshot of the ASUS firmware download page

For routers with USB ports, ASUS has moved “Download Master” (a program that controls downloads on your router) to a USB application. A USB application is one that runs off USB storage, and that makes sense since you need to attach some form of storage to download your files to. The same goes for a “media server”, which I assume is a DLNA server that serves your media files. This way, the firmware image can be made small enough to be used by most routers and still not compromise on functionality. The USB application can also be updated independently from the router firmware.

To run our own programs, we will tap this USB application functionality baked into the ASUSWRT firmware.

Running Programs on the ASUSWRT

When a USB storage device is inserted into the router’s USB port, the rc system daemon mounts the partition and checks for the existence of an asusware/.asusrouter script on the mount point. If it exists, the asusware folder is then symlinked to /tmp/opt (and also /opt) and the script is executed. Since this is all open source, you can find the relevant code in the mount_partition function in release/src/router/rc/usb.c.

This .asusrouter auto-run script is created as part of the Optware installation when you try to install one of the USB applications from the router’s web UI, which you can also manually do from the router’s telnet interface. The asuswrt-merlin github wiki contains more step-by-step guides with screenshots. However, installing Optware is not necessary to get your programs to run – the auto-run script alone will suffice.

Put the commands you wish to execute in asusware/.asusrouter on your USB storage device. Like any shell script, make sure it has #!/bin/sh as its first line and that the file uses UNIX line endings. The filesystem can be anything supported by the kernel – ext2, ext3 or fat. If you are using a filesystem that implements Linux permissions (such as ext2 or ext3), be sure to set the script as executable.

One caveat when running network programs (like DHCP forwarder or mDNS repeater) is that you need to wait until everything has been initialized. ASUS does that by polling the success_start_service NVRAM variable with this bash snippet:

i=0
while [ $i -le 20 ]; do
      success_start_service=`nvram get success_start_service`
      if [ "$success_start_service" == "1" ]; then
              break
      fi
      i=$(($i+1))
      echo "autorun APP: wait $i seconds...";
      sleep 1
done

When the router starts up, it automatically detects plugged-in devices, so I just left a small USB stick permanently in one of the ports.

photo of ASUS router ports, with a USB stick connected

Cross-compiling Programs for the ASUSWRT

ASUS was nice enough to include the cross-compilation toolchain in the source code. You can find the source code (which also contains the toolchain) on the very same ASUS download page for the firmware.

The source code has a README.txt that describes how to setup your development environment, which I assume you have already read or be familiar with. To perform the compilations described here, you need only ensure that your $PATH contains the directory to the cross-compilation toolchain. I unpacked the source code in my home directory, so I just need this line:

export PATH=$PATH:~/asuswrt/tools/brcm/hndtools-mipsel-uclibc/bin

To check that it works correctly, you should be able to execute mipsel-linux-uclibc-gcc.

DHCP Forwarder

DHCP forwarder requires some minor fix up to get it to compile properly, or maybe I’m doing something wrong. I’m using version 0.10, the latest version available on the site. It’s a standard configure and make program, so it’s the configure command-line that is important:

./configure --host=mipsel-linux-uclibc --enable-release

After configure has done its work, some changes need to be made to the generated config.h file for successful compilation. Open config.h and search for the term "rpl_malloc". You will find a #define that replaces malloc with rpl_malloc. This line needs to be commented (or removed) since malloc is available in uClibc.

/* Define to rpl_malloc if the replacement function should be used. */
//#define malloc rpl_malloc

After commenting that line, simply run make and the dhcp-fwd binary (among other things) will be produced.

mDNS Repeater

This one is easy – it invokes only gcc and uses make only:

make CC=mipsel-linux-uclibc-gcc

I have also uploaded the binary onto the repository’s download page, so that you can avoid having to recompile it yourself.

Setting Up DHCP Forwarder

ASUSWRT uses dnsmasq to forward DNS queries and provide DHCP service. In order to install the DHCP forwarder, the DHCP service needs to be disabled. This can be done from the web interface under “LAN”, and selecting the “DHCP Server” tab. ASUSWRT will then replace the DHCP configuration lines in /etc/dnsmasq.conf with no-dhcp-interface=br0 and more importantly, stop listening on the DHCP port.

My dhcp-fwd.conf is copied from the DD-WRT router and the interface names have been changed for the RT-N56U, where br0 is the wireless & LAN ports and eth3 is the WAN port:

user            nobody
group           nobody
chroot          /var/run/dhcp-fwd
logfile         /tmp/dhcp-fwd.log
loglevel        1
pidfile         /var/run/dhcp-fwd.pid
ulimit core     0
ulimit stack    64K
ulimit data     32K
ulimit rss      200K
ulimit nproc    0
ulimit nofile   0
ulimit as       0
if      br0     true    false   true
if      eth3    false   true    true
name    br0     ws-c
server  ip      192.168.0.1

If you’re feeling adventurous, the router interface names and IP addresses can be retrieved from NVRAM using the nvram command. Here’s a bash snippet that obtains the LAN & WAN interface names, as well as the assigned WAN gateway address:

LAN_IFNAME=`nvram get lan_ifname`
WAN_IFNAME=`nvram get wan_ifname`
WAN_GATEWAY=`nvram get wan_gateway`

Conclusion

It seems like ASUS routers that run ASUSWRT are already quite flexible. If you do not need the additional features offered by alternative firmwares, then this hack is just right for you.

Have fun hacking your ASUS router!

Update 21-Apr-13: After upgrading to firmware version 3.0.0.4.360, I spent an entire evening getting my configuration to work. The router is configured to consult a RADIUS server (reachable through the WAN port), but the RADIUS server never gets the request. I have to go to the RADIUS Setting page and click Apply to “wake it up” or something. I noticed that doing this restarts rtinicapd and rt2860apd, so I tried to find a command I could call from the .asusrouter script to trigger this. It was a quick hack, but I found that calling /sbin/restart_wireless does the job. I reconfigured everything from scratch, so I didn’t have time to investigate if it was an ASUSWRT bug, or if starting dhcp-fwd affected something. As long as my wireless is up, I’m happy leaving it as-is.

Advertisements

14 comments on “Hacking Functionality into ASUSWRT Routers

  1. Pele says:

    How can I programatically change the IP address on this router, ie., access the menu release and renew the IP address. Is this possible?

    • darell tan says:

      I think asuswrt uses udhcpc for obtaining leases, but I’m not sure because I’m not using it (and I don’t want to reconfigure my router). According to the README.udhcpc file, sending SIGUSR1 to udhcpc renews the lease where SIGUSR2 releases the current lease.

      Hope that helps.

  2. genti says:

    any luck running cronjobs? it seems that the command crond is there, but you can’t run any cronjobs. I was hoping to run a certain script regularly

    • darell tan says:

      Works for me. The crontab should be in /var/spool/cron/crontabs/admin and you need to start crond first.

      • genti says:

        works for me now as well now. had given a username in the file. which lead to command not found. have to start crond through .asusrouter though. not much of a problem.

  3. Mike says:

    any chance you’d share your current script? I haven’t been able to get it to work (only need mDNS-repeater).

    • darell tan says:

      Hi Mike, I’ve put my script up here:

      Hope that helps.

      • Mike says:

        great – thanks so much!

        • Mike says:

          looks like its running (and my version was as well)… just not having any luck getting it to repeat mDNS to the vpn IPs for some reason. (want to use my iphone on LTE, VPN in to the router, and use bonjour to discover my iTunes server, then stream videos (using the ‘Video’ default app and the ‘shared’ button that it appears in it when it discovers an iTunes library on the same network). Have to travel for a few weeks but will try messing with it again when i get back. thanks again for the script!

  4. […] from chip vendors). That makes the (benevolent) hackers easier to create custom firmware. Although stock AsusWrt is already quite flexible for hackers, custom firmware such as AsusWrt-Merlin is even more flexible. AsusWrt-Merlin however does not […]

  5. maciekish says:

    Can i somehow disable, or change the port od the DNS server? I don’t want it and i want to run something else on UDP port 53 😉

    • darell tan says:

      Yes, you can do almost anything. Just kill the DNS server, replace its config file and restart. The problem would be to synchronize when to do this, and if the user changes some config in the UI, the system might overwrite your config file and restart the DNS server.

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s