Using Router in Dormitory - Cross Compiling MiniEAP for Asuswrt-Merlin
Well, actually I don’t want too many people in my university to know this, so I decided to write this blog in English and not to mention the name of my school clearly here. You can find the name in the blog, if it isn’t your school, hopefully, the part of cross compiling can help you.
I have two routers in my dormitory. During the last year, the software, called MiniEAP, ran on my Redmi router, and another router, manufactured by Netgear, allowed me to use 5GHz WLAN in 64 Channel, which is disabled in my Redmi router. It’s pretty annoying, not only because of those messy cables, but also because when I want to connect to my Netgear router via ssh, I have to plug in another network cable to connect. That’s why I finally decided to spend my Saturday finishing it. (COVID-19 sucks. I want to play maimai in game centre)
I decided to cross compile MiniEAP for my Netgear R6900, which is running Asuswrt-Merlin. To get started, you need Linux. I am using Debian sid, but you can use any distro you like. Anyway, it is still a better choice to check the wiki…
I found a docker on the Internet, and someone used it on macOS, but I haven’t tried yet, so I will use Debian sid to introduce.
Preparation
Dependencies
To build the environment, some packages need to be installed at first. In fact, you can find those packages everywhere on the Internet. Here is what I used:
sudo apt --no-install-recommends install autoconf automake bash bison bzip2 diffutils file flex g++ gawk gcc-multilib gettext gperf groff-base libncurses-dev libexpat1-dev libslang2 libssl-dev libtool libxml-parser-perl make patch perl pkg-config python sed shtool tar texinfo unzip zlib1g zlib1g-dev lib32z1-dev lib32stdc++6 automake1.11
Also add i386 arch to package dependencies (I guess no one uses 32 bits or x86 here):
sudo dpkg --add-architecture i386
sudo apt-get update
sudo apt-get install libelf-dev:i386 libelf1:i386
Source Code
Maybe you have noticed that the repository had transferred to asuswrt-merlin.ng, and the old one had archived. However, it seems that it doesn’t include toolchains in asuswrt-merlin.ng. The toolchains is in another repository:
git clone https://github.com/RMerl/am-toolchains.git
And don’t forget MiniEAP:
git clone https://github.com/updateing/minieap.git
For my university, the patches are necessary. These patches were used by GZHU originally, but they can be used at my university as well.
git clone https://github.com/ysc3839/openwrt-minieap.git package/minieap
Applying Patches
In HOME we have two folders, minieap/ and openwrt-minieap/. Now cd to minieap/, then try these commands:
patch -p1 < ~/openwrt-minieap/patches/001-enable-gbconv.patch
patch -p1 < ~/openwrt-minieap/patches/002-remove-date-in-log-message.patch
patch -p1 < ~/openwrt-minieap/patches/003-disable-hdd-serial-query-and-show-warning.patch
patch -p1 < ~/openwrt-minieap/patches/004-fix-logging-buffer.patch
patch -p1 < ~/openwrt-minieap/patches/005-remove-pid-check-warn.patch

Actually, I want to use an asterisk to get them done at once, but it threw me this… wtf
Environment
After patching, we need to create some symlinks. For my router, R6900, I just need to focus on BCM-SDK :
sudo ln -s ~/am-toolchains/brcm-arm-sdk/hndtools-arm-linux-2.6.36-uclibc-4.5.3 /opt/brcm-arm
echo "PATH=\$PATH:/opt/brcm-arm/bin" >> ~/.profile
With those commands, while compiling, probably you won’t succeed. Maybe you will get this after the ldd command:
$ ldd /opt/brcm-arm/libexec/gcc/arm-brcm-linux-uclibcgnueabi/4.5.3/cc1
linux-gate.so.1 => (0xf77bf000)
libmpc.so.2 => not found
libmpfr.so.4 => not found
libgmp.so.10 => not found
libdl.so.2 => /lib/i386-linux-gnu/libdl.so.2 (0xf77aa000)
libelf.so.1 => /usr/lib/i386-linux-gnu/libelf.so.1 (0xf7792000)
libc.so.6 => /lib/i386-linux-gnu/libc.so.6 (0xf75e3000)
/lib/ld-linux.so.2 (0xf77c0000)
Some libraries are missing. So you need:
export LD_LIBRARY_PATH=${LD_LIBRARY_PATH}:/opt/brcm-arm/lib:/usr/local/lib:/usr/lib
That’s all.
$ ldd /opt/brcm-arm/libexec/gcc/arm-brcm-linux-uclibcgnueabi/4.5.3/cc1
linux-gate.so.1 (0xf7f98000)
libmpc.so.2 => /opt/brcm-arm/lib/libmpc.so.2 (0xf7f7f000)
libmpfr.so.4 => /opt/brcm-arm/lib/libmpfr.so.4 (0xf7f30000)
libgmp.so.10 => /opt/brcm-arm/lib/libgmp.so.10 (0xf7ed3000)
libdl.so.2 => /lib/i386-linux-gnu/libdl.so.2 (0xf7ead000)
libelf.so.1 => /lib/i386-linux-gnu/libelf.so.1 (0xf7e8f000)
libc.so.6 => /lib/i386-linux-gnu/libc.so.6 (0xf7ca6000)
libm.so.6 => /lib/i386-linux-gnu/libm.so.6 (0xf7ba2000)
/lib/ld-linux.so.2 (0xf7f9a000)
libz.so.1 => /lib/i386-linux-gnu/libz.so.1 (0xf7b85000)
Cross Compiling
I would like to deal with it one file by one file.
minieap/config.mk
config.mk is used for compiling, just like its filename. I would like a simple and violent method, just directly add this on the last of the file:
CC := ~/am-toolchains/brcm-arm-sdk/hndtools-arm-linux-2.6.36-uclibc-4.5.3/bin/arm-uclibc-linux-2.6.36-gcc
As I failed for many times, so even I know I shouldn’t do like this, I am a little bit annoyed at last. Plz adjust the paths for your own environment if necessary.
Also remove the “#” in front of PLUGIN_MODULES += ifaddrs, as we need to use it later.
After all, the config.mk without comments looks like this:
PLUGIN_MODULES := \
packet_plugin_printer \
packet_plugin_rjv3
PLUGIN_MODULES += if_impl_sockraw
ENABLE_DEBUG := false
ENABLE_ICONV := false
ENABLE_GBCONV := true
STATIC_BUILD := false
LIBICONV_STANDALONE := false
CUSTOM_CFLAGS :=
CUSTOM_LDFLAGS :=
CUSTOM_LIBS :=
CC := ~/am-toolchains/brcm-arm-sdk/hndtools-arm-linux-2.6.36-uclibc-4.5.3/bin/arm-uclibc-linux-2.6.36-gcc
PLUGIN_MODULES += ifaddrs
minieap/Makefile
If you run make directly, you will get an error about -Wpedantic, which isn’t supported by the version of gcc. Just replace it with -std=gnu99:
4c4
< COMMON_CFLAGS := $(CUSTOM_CFLAGS) $(CFLAGS) -Wall -Wpedantic -D_GNU_SOURCE
---
> COMMON_CFLAGS := $(CUSTOM_CFLAGS) $(CFLAGS) -Wall -std=gnu99 -D_GNU_SOURCE
(You can find the tip use option -std=c99 or -std=gnu99 to compile your code if you just remove -Wpedantic, but it seems that using -std=c99 will cause some syntax errors.)
ifaddrs
Then, if you start compiling, you will get this sh*t:
util/net_util.o: In function `obtain_iface_mac':
net_util.c:(.text+0xa8): undefined reference to `getifaddrs'
net_util.c:(.text+0x180): undefined reference to `freeifaddrs'
util/net_util.o: In function `obtain_iface_ip_mask':
net_util.c:(.text+0x1b0): undefined reference to `getifaddrs'
net_util.c:(.text+0x36c): undefined reference to `freeifaddrs'
collect2: ld returned 1 exit status
It doesn’t find those functions that the platform doesn’t provide, so we need to add those files ourselves. That’s why I add PLUGIN_MODULES += ifaddrs in config.mk before, as it enables us to use those files.
Don’t worry, we still have mighty GitHub. Many files can be found on GitHub. I used this ifaddrs.c and this ifaddrs.h. I know little about C or C++, so I can’t give too much advice. Add ifaddrs.h in includes/ and add ifaddrs.c in util/ifaddrs/. Don’t forget to edit config.mk if you didn’t do it before.
After all things are done, enter make and start compiling. Compiling MiniEAP is pretty fast. You can type file minieap to check if everything is fine.

RUN!
Using scp or any other method to upload the file to your router. Type ./minieap you will get a message asking you to login. With -w, you can save the configuration to /etc/minieap.conf. Don’t forget to move your files (one is your minieap program and another is the /etc/minieap.conf) to /jffs, or the files will disappear after rebooting.
There’re some problems:
Auto Reboot
To use crontab in Arsuswrt-Merlin is a complex thing, as everything not in /jffs will be deleted. However, we have this on wiki. Just refer to it.
Auto Reauth
According to this issue, you need to delete no-auto-reauth to enable auto reauth. It is simple, but I still can’t reauth, but it is worth trying.
My solution is ping. Here is my script:
#!/bin/sh
while true
do
ping -q -c 3 cn.bing.com >> /dev/null
if [ $? -eq 0 ]
then
echo "[`date`]Everything is fine."
else
echo "[`date`]Failed. Restarting minieap." >> /var/log/watchdog.log
/jffs/minieap/minieap
fi
done
It means if the router cannot ping cn.bing.com successfully, it will write a log in /var/log/watchdog.log and restart MiniEAP. In fact, I don’t want any outputs, as my MiniEAP disconnects every 20 seconds…

In User scripts, we have wan-script, add these three lines in the script:
cp /jffs/minieap/minieap.conf /etc/
/jffs/minieap/minieap
/jffs/minieap/watchdog.sh
Adjust the paths for your own environment if necessary.
wan-script contains the scripts that will run after the WAN interface comes up, in the new version of Asuswrt-Merlin, it has been replaced by wan-start. The first line means copy new minieap.conf to /etc, as everything has gone after rebooting. Then it restarts MiniEAP. Finally, the watchdog.sh will run to keep auth.
Now enjoy your Campus Internet. Everything is fine.