Hi Kevin!
Here are my results:
1. I downloaded a DD-WRT v24-sp2 build for the Netgear WNDR4500v1 from
http://www.myopenrouter.com/download/43858/DD-WRT-for-WNDR4500v1/
2. I grabbed the DD-WRT mipsel toolchain used to build the above from
http://www.myopenrouter.com/download/38650/DD-WRT-Toolchain/
3. The adb build you provided needs librt, which isn't provided in the firmware. The toolchain I downloaded has librt, so I loaded up your adb, klink, and the toolchain (minus the static libraries) on my ext2-formatted USB flash drive and used:
LD_LIBRARY_PATH=the_toolchain ./adb nodaemon server
This got me further, but apparently the "atexit" symbol wasn't defined by the uclibc 0.9.32 build in the toolchain, so I ended up having to recompile adb after all due to this linkage problem.
I recompiled adb using the Ubuntu 12.10 android-tools-adb package sources from
http://packages.ubuntu.com/quantal/android-tools-adb (they provide a standalone Makefile, which I only had to *lightly* modify by grabbing Android's upstream zlib sources and building them and hooking up the headers and lib into the Makefile). I also had to ship libz.so to the flash drive and the new adb binary.
4. This got me further. "adb" now runs without any errors, and is able to fork its server process into the background without complaint, and it'll run just fine. Klink can spawn adb (in the same directory) without copying it into /usr/share/klink, and everything IN USERSPACE looks cool. Even ./adb nodaemon server will just sit there silently (happily).
Unfortunately, "./adb devices" fails silently, and "./adb usb" returns "error: device not found", even when I have my phone plugged into the router and the handset says "USB Debugging Connected" and shows the little bug icon in the notification area.
Figuring it was a power problem, I switched to a powered USB hub, which makes my handset say "Charging" when the battery isn't 100%, but the problem remains. I *doubt* it is an ADB problem at this point; it may actually be a kernel problem (missing feature or something not compiled in). Or something *else* is up.
5. After ** A LOT ** of "hmming" and "hawing" about this problem, I eventually made the connection between this line in Android sources, system/core/adb/usb_linux.c line 689 and the PROBLEM:
find_usb_device("/dev/bus/usb", register_device);
Ha ha! A hard coded path! And guess what. It didn't exist on my router.
I had a mini-panic, thinking I had an incompatible kernel or the wrong kernel version.
Nope.
# ln -s /proc/bus/ /dev/bus
As soon as I did this and re-ran Klink, it immediately started and sprung to life. ADB detected my device, and we're off to the races! Klink client running AND WORKING on MIPS! I'm writing you this message connected to my extremely fragile configuration over Ethernet.
The rest, as they say, is history. I had to set up some routing rules to set the default gateway to the Klink gateway (10.0.0.1) and set a static IP for the klink0 iface. I had to tweak iptables configuration to do IP masquerading from DD-WRT' "br0" (NAT interface) to the Klink interface. But...... IT WORKS!!!!!!!! It COMPLETELY works!
So, now, here are the steps that are needed (no custom firmware needed!), assuming the adb compile is already taken care of, and a few notes:
Note 1: The "tun" device is compiled statically into the Linux kernel in the firmware I'm using, so no need to insmod/modprobe it.
Note 2: I'm assuming DD-WRT v24 or thereabouts. Very old DD-WRT, OpenWRT, CeroWRT, etc. are going to behave very differently, and some of these steps may break. This stuff is running pretty close to the operating system and the hardware, so significant version changes can have... significant impacts ;)
Note 3: Depending on how many other USB storage devices you attach, and other version/hardware-specific settings, you may need to change the value assigned to the EXTDEVPATH variable in the script in step 5. On DD-WRT v24-sp2, the operating system automatically mounts the first partition of the first USB mass storage device to /tmp/mnt/disc0_part1, so that's what I'm using.
Hardware note: most handsets draw more energy from the USB port than a low-powered router can be expected to provide. Also, if you're doing this with a different router model and it doesn't have two USB ports like mine, this is absolutely essential. Either way, you need a good, *POWERED* USB hub: either for the extra juice, for the two ports, or both.
Another hardware note: You need a USB Mass Storage device that can be detected and mounted by your router's firmware. Try not to use anything too exotic. A common USB flash drive or small hard drive should be fine. You should need less than 100 MB of space on it.
1. Obtain a working copy of adb for your router (I can provide mine and my toolchain libs if anyone wants them) -- see the email above for details.
2. Download the Klink client binary for MIPS
3. Using your workstation, shove adb, klink, and any support libraries needed by adb onto an ext2-formatted flash drive or hard drive. Use a Linux computer / virtual machine / live CD to do the format, or maybe some Windows tool exists, I don't know.
4. Connect the USB flash drive to the router. It'll need to always be in the router when the router is booted, unless you figure out how to copy its contents into a RAMdisk and remove it (I haven't gotten that far yet).
5. Enable SSH or Telnet (preferably SSH) to your router. This is important, because SSH is slow.
6. You need to run the following commands. You can create a script on the flash drive with these commands and run it when you start the router, OR you can use a startup script in NVRAM so that this launches on boot (see
http://www.dd-wrt.com/wiki/index.php/Startup_Scripts ):
#!/bin/sh
export EXTDEVPATH=/tmp/mnt/disc0_part1
export LD_LIBRARY_PATH=/tmp/stuff/lib
mkdir -p /tmp/stuff
ln -s /proc/bus /dev/bus
while [ ! -f ${EXTDEVPATH}/klink ]
do
sleep 5
done
cd ${EXTDEVPATH}
cp -rf adb klink lib/ /tmp/stuff/
cd /tmp/stuff
while [ /bin/true ]
do
/tmp/stuff/adb start-server
/tmp/stuff/adb wait-for-device
/tmp/stuff/klink &
export KLINK_PID=$!
sleep 5
ifconfig klink0 up
ifconfig klink0 10.0.0.3
ifconfig klink0 netmask 255.0.0.0
echo nameserver 8.8.8.8 > /etc/resolv.conf
route add default gw 10.0.0.1 klink0
iptables -I FORWARD -j ACCEPT
if [ ! -z $KLINK_PID ]
then
wait $KLINK_PID
fi
done
7. Now, here's where I'm stuck. Here's what works and doesn't work:
* It WORKS if I try to access the public Internet from the router itself (SSH'ed in).
* It WORKS if I have the router do NAT, so that you have a NAT on the router (e.g. 192.168.1.0 netmask 255.255.255.0) and a NAT inside Klink (e.g. 10.0.0.0 netmask 255.0.0.0). Even my computer can surf the web.
* It DOESN'T WORK if I put Klink, eth0, eth1, vlan1 and vlan2 in an ethernet bridge (using brctl) trying to eliminate the redundant NAT on the router and use Klink's NAT directly. I configure my client PC with IP 10.0.0.4 netmask 255.0.0.0 gateway 10.0.0.1 (also tried 10.0.0.2 with a static route), and I configure the br0 interface on the router with IP 10.0.0.2 netmask 255.0.0.0, and set the default gateway as in the script above. This SHOULD be enough to create an ethernet bridge between Klink and my computer, right? Well apparently not because it doesn't work.
So basically if I try to get the router to act as a "Gateway" that just happens to have its downstream default gateway set to Klink, it works. But if I get the router to act as a Layer 2 "Switch/Hub" (the Linux software bridge), it doesn't work. Maybe I'm missing something. Maybe it's a problem with DD-WRT. But it sure is unpleasant, and I want to get to the bottom of it, because I'm under the (perhaps false) impression that there is lower latency and overhead with an ethernet bridge than with nested NAT layers..
Sorry for the long email. I'm just happy I got the Klink side to work at all. For now I'm running my system in the inefficient NAT -> NAT mode so I have a working internet connection, but I'd like to fix bridged mode. Is this a limitation of Klink that it doesn't work?
Thanks,
Sean