I've just finished getting avahi up & running on my Asus RT-N16, and configured to advertise the following services:
- Tomato's admin webif
- shared USB printing
- ssh login
- a few others…
It works perfectly, but is still a work in progress, has some of cruft under the hood, and could be pared down a lot (so it could fit in routers that have a smaller flash chip)…nevertheless…
It is useful,
- since any Bonjour-enabled web browser can find the webif automagically,
- the printer automatically advertises itself over the network, so it is easier to set up, and
- in general, all services can be advertised over the network and are easier to configure on the client.
This isn't all my original idea… avahi & Bonjour have been around for years, and "howl" also has been around for a long time. When I was working/helping with foonas (foonas.org), it was used to advertise the AFP protocol for an opensource TimeCapsule (alternative to Apple's product) and for p910nd as well. The article here Adventures w/ dd-wrt and Avahi is definitely dd-wrt-centric, but it gave me a foothold/template for what to do.
Tomato and dd-wrt are far from identical, so what I did was not identical to what was done in the article, but it follows the same idea. There is definitely cruft here… I share this with the thought that others will try it, find it useful, and make improvements and clean up the cruft and any errors.
This is roughly what I did:
1. Install TomatoUSB Ext, configure & check that I have telnet/internet access and can reach the servers that have the Optware feeds.
- I used the dd-wrt mini rt-n16 build as a preliminary step to install the latest Ext build for the R2 chipset. Be careful that you have enough space on your router.
- Set your network parameters so that you can ping something like yahoo.com, and change the hostname from 'unknown' to whatever you want.
- Test that you have telnet access.
2. Set up the jffs partition, install Optware and adjust some directories & symlinks so that flash is not overused.
*In the Admin:JFFS page, enable and format the jffs partition. This will give you persistent storage on the flash chip.
*Install Optware, either in /jffs, on a USB hdd, or some other location, according to this excellent guide from dd-wrt . I basically followed steps 2.1-2.2. Even routers with just a little space in jffs can be fitted with optware, using an attached USB drive. Since my RT-N16 has a lot of space for jffs, I didn't use the usb storage for /opt.
mkdir /jffs/opt mount -o bind /jffs/opt /opt wget http://www.3iii.dk/linux/optware/optware-install-ddwrt.sh -O - | tr -d '\r' > /tmp/optware-install.sh sh /tmp/optware-install.sh
These commands make a dir call opt in /jffs, bind that dir to /opt, download a script that will take care of the ipkg package-handler and some uclibc components, and finally the last command executes that script.
You should see something similar to this:
Checking system config …
Using 192.168.1.1 as default gateway.
Using the following nameserver(s):
Warning: local nameserver is different than gateway!
Check config or enter:
sed -i s/192.168.*/192.168.1.1/ /tmp/resolv.conf
to correct this.
Installing package uclibc-opt_0.9.28-13_mipsel.ipk …
Connecting to ipkg.nslu2-linux.org[188.8.131.52]:80
uclibc-opt_0.9.28-12 100% |*| 832 KB 00:00:00 ETA
/opt/sbin/ldconfig: can't create /opt/etc/ld.so.cache~ (No such file or directory)
Installing package ipkg-opt_0.99.163-9_mipsel.ipk …
Connecting to ipkg.nslu2-linux.org[184.108.40.206]:80
ipkg-opt_0.99.163-9_ 100% |*| 75896 00:00:00 ETA
Updated list of available packages in /opt/lib/ipkg/lists/optware
Installing uclibc-opt (0.9.28-12) to /opt/…
package uclibc-opt suggests installing ipkg-opt
Installing ipkg-opt (0.99.163-9) to /opt/…
You can read a bit more about how ipkg works at the dd-wrt Optware instruction page.
Now we take care of a potential problem: over-use of the flash memory. /opt/var is in /jffs, really, and we don't want to do too many writes to jffs. So we will delete the actual directory, and replace it with a symlink to /tmp/var, which is in (non-persistent) RAM.
rm -r /opt/var ln -s /tmp/var /opt/var
Now fire up ipkg and install avahi and its dependencies.
/opt/bin/ipkg-opt --tmp-dir /tmp install avahi unzip
This will install avahi, dbus, expat and a bunch of other packages. Unfortunately, the optware maintainers didn't configure the build of dbus the way we need, it so you have to force a reinstall of a "good" dbus package. Download/wget it from here : discussion about broken ipkg 's in the optware feed : get the file dbus_1.2.16-2_mipsel.ipk.zip, unzip it, and then force installation.
cd /tmp wget http://www.dd-wrt.com/phpBB2/download.php?id=14992&sid=bc4f40382d4c2fa597a8cdf6aa8ef452 mv download.php?id\=14992 dbus-nopie-option.zip unzip dbus-nopie-option.zip ipkg -force-depends install dbus_1.2.16-2_mipsel.ipk
3. Add in some scripts in /jffs and in the webif to start services at the right time during the boot process.
In the webif, in Admin:Scripts:Firewall, I added in the following:
sleep 5 mount -o bind /jffs/opt /opt mount -f -o noatime,remount -t ext3 /dev/scsi/host0/bus0/target0/lun0/part1 /opt echo "netdev:x:1:" >> /tmp/etc/group echo "avahi:x:2:" >> /tmp/etc/group echo "avahi:x:2:2:avahi daemon:/opt/sbin/avahi-daemon:/bin/false" >> /tmp/etc/passwd sleep 5 for f in /opt/etc/init.d/S* ; do [ -x $f ] && $f start ; done sleep 5 for f in /opt/etc/init.d/S* ; do [ -x $f ] && $f start ; done
The sleeps are for some pause time for things to settle, the mounts are to mount and bind /opt and /jffs properly. The echos are to add in groups and password settings. Since most of the rootfs is read-only, these have to be executed at each boot. The two [[code]]
for ; do ; done
[[/code]] structures are for starting the optware-based services of dbus and avahi.
Cruft alert: Yes, I know there are two occurences. I'm not 100% sure what the problem is or why two starts are needed to get dbus and avahi both successfully up. I suspect it is something to do with the chown command around line 90? in the dbus init script.
The dbus init script is included in the ipkg, and it resides at /opt/etc/init.d/S20dbus. Oddly, the optware maintainers did not provide an initscript for avahi-daemon, so we must add in one manually at /opt/etc/init.d/S21avahi-daemon as follows:
#!/bin/sh EXE=avahi-daemon BIN=/opt/sbin/$EXE OPTIONS="-D" RUN_D=/opt/var/run/$EXE case $1 in start) mkdir -p $RUN_D $BIN $OPTIONS ;; stop) $BIN -k ;; reload) if [ -f $RUN_D/pid ]; then $BIN -r; else mkdir -p $RUN_D; $BIN $OPTIONS; fi ;; restart) if [ -f $RUN_D/pid ]; then $BIN -k fi mkdir -p $RUN_D $BIN $OPTIONS ;; *) echo "usage: $0 (start|stop|reload|restart)" exit 1 esac exit $?
4. Tweak avahi's config with some definitions of services that you will probably be running.
For shared USB printing, here is a definition that should be created at /opt/etc/avahi/services/p910nd.service.
<name replace-wildcards="yes">p910nd printer on %h</name>
<txt-record>product=usb shared network printer</txt-record>
So that any Bonjour-enabled webbrowser can easily find the Tomato webif, add this at /opt/etc/avahi/services/webif.service :
<?xml version="1.0" standalone='no'?><!*-nxml-*>
<!DOCTYPE service-group SYSTEM "avahi-service.dtd">
<name replace-wildcards="yes">%h admin webif</name>
Research on your own how to add more service definitions such as Samba, if you wish.
5. Restart and enjoy. If you use OS X, Linux (or to a lesser extent, Windows w/ Bonjour installed) you will be able to configure your client more easily now.
If you use these directions, please keep a record of your results, and post back with problems that you found.
Various Broadcom Routers Running TomatoUSB (or DD-WRT) with Airprint & Cloud Print
See my Repo's at http://github.com/davygravy
Extra/Newer Optware ipks not in the dd-wrt/nslu2 feed
davy's 1-wire weather, courtesy of TomatoUSB, Optware & Maxi