fix openwrt network script bug

一 23rd, 2012

On my router there are some interfaces in /etc/config/network. The wan interface is configured as a PPPOE netowrk to connect my ISP. There is also a pptp-vpn connected named zvpn. I found it is very slow to run “/etc/init.d/network reload”, taking about 2 miniutes. If I comment out the zvpn interface, it runs fast.

Obviously, the vpn connection depends on my main connection — the wan interface which works in PPPOE mode. So this should be the key point. I spent many hours before to find how to config the dependency, including asking this question in the openwrt forum, but with no luck.  Today I wrote some debug statements in the network scripts and almost brick my router to find what is wrong, finaly I got it.

I thought it is because the vpn interface is inited before wan, so I named my vpn interface as zvpn to make it as the last one,  but I’m wrong.  I don’t need to care its name.  The network scripts load each interface in the order of what it is in the configration file — /etc/config/network. However, there is a problem: the network scripts also unload each interface in this order.

We know, the unload order should be the reverse of the load order. This can be changed by patch /sbin/ifdown.

This is the patch:

--- /rom/sbin/ifdown        2012-01-21 22:21:29.000000000 +0800
+++ ifdown      2012-01-23 17:23:46.000000000 +0800
@@ -7,10 +7,17 @@
 case "$1" in
        "-a")
                [ -e "/tmp/resolv.conf.auto" ] && rm /tmp/resolv.conf.auto
+               TODO=
                config_cb() {
-                       [ interface != "$1" -o -z "$2" ] || eval "$0 -w $2"
+                       [ interface != "$1" -o -z "$2" ] || TODO="$2 $TODO"
                }
                config_load network
+               for i in $TODO ; do
+                       $0 -w $i
+               done
                exit 0
        ;;
        "-w") shift ;;

Openwrt has a recovery mode that helps me to unbrick my router after I made some bad modifications to the config files. To enter this mode, power off the router, hold reset button, power on, keep holding reset button until 192.168.1.1 replying ping requests. Then just telnet 192.168.1.1, mount -t jffs2 /dev/mtdblock3 /overlay/, and fix problems there.

标签:

install vmware tools on debian (guest) for newest kernel (3.1.0)

一 19th, 2012

vmware version: vmware workstation 8.0.1 build-528992
debian kernel: 3.1.0-1-486
vmware tools fails to install or run.

solution:
1. apt-get install libglib2.0-0
2. patch /usr/lib/vmware-tools/modules/source/vmhgfs.tar
unpack vmhgfs.tar, patch, repack.
the patch:

diff -ur vmhgfs-only-old/file.c vmhgfs-only/file.c
--- vmhgfs-only-old/file.c      2011-11-14 11:41:31.000000000 +0800
+++ vmhgfs-only/file.c  2012-01-19 17:59:47.899616529 +0800
@@ -84,6 +84,8 @@
 #if defined VMW_FSYNC_OLD
                      struct dentry *dentry,
 #endif
+                                        loff_t start,
+                                        loff_t end,
                      int datasync);
 static int HgfsMmap(struct file *file,
                     struct vm_area_struct *vma);
@@ -990,6 +992,8 @@
 #if defined VMW_FSYNC_OLD
           struct dentry *dentry,        // IN: Dentry for this file
 #endif
+                 loff_t start,
+                 loff_t end,
           int datasync)                        // IN: fdatasync or fsync
 {
    LOG(6, (KERN_DEBUG "VMware hgfs: HgfsFsync: was called\n"));
diff -ur vmhgfs-only-old/filesystem.c vmhgfs-only/filesystem.c
--- vmhgfs-only-old/filesystem.c        2011-11-14 11:41:31.000000000 +0800
+++ vmhgfs-only/filesystem.c    2012-01-19 16:41:00.303867660 +0800
@@ -358,6 +358,8 @@
    HgfsSuperInfo *si;
    HgfsMountInfo *mountInfo;
    struct dentry *rootDentry;
+   struct dentry *tmpDentry;
+   struct inode *inode;
 
    ASSERT(sb);
 
@@ -408,15 +410,15 @@
     * and superblock. Then HgfsInstantiate will do the rest, issuing a getattr,
     * getting the inode, and instantiating the dentry with it.
     */
-   rootDentry = compat_d_alloc_name(NULL, "/");
+   inode = new_inode(sb);
+   tmpDentry = d_alloc_root(inode);
+   rootDentry = compat_d_alloc_name(tmpDentry, "/");
    if (rootDentry == NULL) {
       LOG(4, (KERN_WARNING "VMware hgfs: HgfsReadSuper: Could not allocate "
               "root dentry\n"));
       result = -ENOMEM;
       goto exit;
    }
-   rootDentry->d_parent = rootDentry;
-   rootDentry->d_sb = sb;
    result = HgfsInstantiate(rootDentry, HGFS_ROOT_INO, NULL);
    if (result) {
       LOG(4, (KERN_WARNING "VMware hgfs: HgfsReadSuper: Could not instantiate "
标签:

some notes for mac osx dev.

一 8th, 2012

set install_name for dylib
g++ -install_name xxx.o -o xxx.dylib

view install_name:
method1: otool -L xxx.dylib see the first row.

change install_name
install_name_tool -change old.dylib new.dylib xxx.dylib

pack libs
lipo -create a_32.dylib a_64.dylib -output a.dylib

标签:

patch mindmanager to avoid fuzzy text.

十二 28th, 2011

mindmanager is a great tool, but it has a bug (or they the devlopers may think it’s a feature) not fixed for years. That is, the fuzzy text problem. Just search mindmanager fuzzy text , there are many results about this bug and some patches for the old versions of mindmanager. Just as what is said from http://forum.us.mindjet.com/viewtopic.php?f=16&t=3060 ,disabling the call to GdipSetTextRenderingHint fixes this bug.

steps to make a patch
1. open a debugger, ex: ollydbg, load mindmanager.
2. break at GdipSetTextRenderingHint (gdiplus.dll!_GdipSetTextRenderingHint@8)
3. when it break down, track the call to it. It’s something like:

00688A2D  call        00CC8792

goto 00CC8792 , it is something like:

00CC8792  jmp         dword ptr ds:[0E5A758h]

change it to :
retn 8
code bytes: c2 08 00 90 90 90
4. save the modification to mindmanager.exe
5. done, enjoy clear text.

标签:

patch openwrt to avoid “bad substitution”

十一 13th, 2011

when editing some configration of openwrt , this error maybe occured:
/sbin/ifup: eval: line 1: syntax error: bad substitution

I found at least one reason of this error code, and fixed it.

--- /rom/lib/network/config.sh
+++ config.sh
@@ -15,7 +15,7 @@
 
        local fam
        for fam in ipv4 ipv6; do
-               if [ -d /proc/sys/net/$fam ]; then
+               if ls /proc/sys/net/$fam/*/$ifn 2>/dev/null ; then
                        local key
                        for key in /proc/sys/net/$fam/*/$ifn/*; do
                                local val

If there is no such file , $key is “/proc/sys/net/ipv4/*/eth1:1/*” before this modification, statements in then case are not executed after modification. so this code resolved the problem of reporting:
/sbin/ifup: eval: line 1: syntax error: bad substitution

标签:

Google’s IP Range

八 30th, 2011

the following ip addresses belong to google.

64.233.160.0 – 64.233.191.255
66.102.0.0 – 66.102.15.255
66.249.64.0 – 66.249.95.255
72.14.192.0 – 72.14.255.255
74.125.0.0 – 74.125.255.255
209.85.128.0 – 209.85.255.255
216.239.32.0 – 216.239.63.255

标签:

定制编译openwrt.

八 14th, 2011

配置完openwrt之后,觉得实在是还不够。想装个tcpdump,结果发现没有空间了。看样子得想办法省出点空间。

仔细看了看openwrt的文件系统结构,发现openwrt是把编译出来的一份只读系统打包了,装载在/rom下,然后,修改新加的内容,单独放在另一个可读写的地方,装载在/overlay上。/rom和/overlay的文件都不是全部,两者结合,才真正形成了一个复合的文件系统,加载于/。对系统文件进行替换后,由于/rom不可写,不要的那个文件并没有真正删除,其空间也就浪费了。这在小小的路由器上,是不可接受的。因此对系统的修改,比如我重新弄了个改完BUG后的dropbear,就实在是大大的浪费。

而且/rom里的文件,实际存储是压缩了的,文件压缩自然可省空间。因此有必要编译一份openwrt。过程:
1. host安装必要的组件: apt-get install gawk flex unzip git subversion
2. 下载源代码。 svn co svn://svn.openwrt.org/openwrt 。从此trunk目录就成了build_root目录。
3. 更新feeds. ./scripts/feeds update -a
4. 安装必须的组件 ./scripts/feeds install tcpdump psmisc
5. make menuconfig,设置一些组件。使得Target System为Atheros AR71xx/AR7240/AR913x/AR934x。Target Profile为TP-LINK TL-WR841ND v7。
6. 继续设置menuconfig里的组件。完了后make defconfig检查,确保得到以下结果:

diff  y
kmod-ipt-nathelper-extra y
kmod-mppe y
kmod-pptp y
pptp y
uhttpd  y
tcpdump y
psmisc m

注意psmisc用Module方式就可以了,因为里面有多个程序,我只需要最重要的pstree。
7. make
8. 修改dropbear bug。见: http://www.swigger.net/archives/291.html
cd ./build_dir/target-mips_r2_uClibc-0.9.32/dropbear-0.53.1

note @2012-01-22: this bug is fixed by dropbear.
9. 修改config.sh ./package/base-files-network/files/lib/network/config.sh
http://www.swigger.net/archives/316.html
- if [ -d /proc/sys/net/$fam ]; then
+ if ls /proc/sys/net/$fam/*/$ifn 2>/dev/null ; then
10. 修改package/base-files-network/files/sbin/ifdown . 见 http://www.swigger.net/archives/336.html
11. 修改 rcS

--- package/base-files/files/etc/init.d/rcS     (revision 29839)
+++ package/base-files/files/etc/init.d/rcS     (working copy)
@@ -4,15 +4,15 @@
 run_scripts() {
        for i in /etc/rc.d/$1*; do
                [ -x $i ] && $i $2 2>&1
-       done | $LOGGER
+       done
 }
 
 system_config() {
        config_get_bool foreground $1 foreground 0
 }
 
-LOGGER="cat"
-[ -x /usr/bin/logger ] && LOGGER="logger -s -p 6 -t sysinit"
+#LOGGER="cat"
+#[ -x /usr/bin/logger ] && LOGGER="logger -s -p 6 -t sysinit"
 
 . /etc/functions.sh

12. 来到build_root目录,执行:

$ mkdir -p files/etc/config
$ mkdir files/etc/ppp
$ cp ./build_dir/target-mips_r2_uClibc-0.9.32/dropbear-0.53.1/ipkg-ar71xx/dropbear/etc/config/dropbear files/etc/config
$ vim files/etc/config/dropbear
+  option GatewayPorts 1
$ cp ./build_dir/target-mips_r2_uClibc-0.9.32/pptp-1.7.1/ipkg-ar71xx/pptp/etc/ppp/options.pptp files/etc/ppp/
$ vim files/etc/ppp/options.pptp
- defaultroute
$ cp build_dir/target-mips_r2_uClibc-0.9.32/root-ar71xx/etc/shells files/etc/
$ vim files/etc/shells
+ /bin/false
$ mkdir -p files/usr/bin
$ cp build_dir/target-mips_r2_uClibc-0.9.32/psmisc-22.13/ipkg-ar71xx/psmisc/usr/bin/pstree files/usr/bin/
$ ./staging_dir/toolchain-mips_r2_gcc-4.5-linaro_uClibc-0.9.32/bin/mips-openwrt-linux-strip files/usr/bin/pstree 
$ make

13. 大功告成。使用 bin/ar71xx/openwrt-ar71xx-generic-tl-wr841nd-v7-squashfs-factory.bin 刷系统。
刷完系统再改改配置文件。(/rom/etc/config下的总是会copy到/overlay/etc/config中,预置配置文件省不了空间)组件就不用装了。
结果是嵌了tcpdump和其它我需要的几个组件,最后还剩下几百K的空间。总的来说成果很好。

root@OpenWrt:~# df
Filesystem           1K-blocks      Used Available Use% Mounted on
/dev/root                 1792      1792         0 100% /rom
tmpfs                    14780        84     14696   1% /tmp
tmpfs                      512         0       512   0% /dev
/dev/mtdblock3             844        80       764   9% /overlay
overlayfs:/overlay         844        80       764   9% /
root@OpenWrt:~# mount
rootfs on / type rootfs (rw)
/dev/root on /rom type squashfs (ro,relatime)
proc on /proc type proc (rw,noatime)
sysfs on /sys type sysfs (rw,noatime)
tmpfs on /tmp type tmpfs (rw,nosuid,nodev,noatime,size=14780k)
tmpfs on /dev type tmpfs (rw,noatime,size=512k,mode=755)
devpts on /dev/pts type devpts (rw,noatime,mode=600)
/dev/mtdblock3 on /overlay type jffs2 (rw,noatime)
overlayfs:/overlay on / type overlayfs (rw,noatime)
debugfs on /sys/kernel/debug type debugfs (rw,relatime)
标签:

simple shell script for help compiling progs for openwrt.

八 13th, 2011
#!/bin/bash
export PATH=/ow/openwrt/trunk/staging_dir/toolchain-mips_r2_gcc-linaro_uClibc-0.9.32/bin/:$PATH
gcc_cmd='mips-openwrt-linux-uclibc-gcc
-I/ow/openwrt/trunk/staging_dir/target-mips_r2_uClibc-0.9.32/usr/include
-I/ow/openwrt/trunk/staging_dir/target-mips_r2_uClibc-0.9.32/include
-I/ow/openwrt/trunk/staging_dir/toolchain-mips_r2_gcc-linaro_uClibc-0.9.32/usr/include
-I/ow/openwrt/trunk/staging_dir/toolchain-mips_r2_gcc-linaro_uClibc-0.9.32/include
 
-Os
-pipe
-mips32r2
-mtune=mips32r2
-fno-caller-saves
-fhonour-copts
-msoft-float
-ffunction-sections
-fdata-sections
 
-L/ow/openwrt/trunk/staging_dir/target-mips_r2_uClibc-0.9.32/usr/lib
-L/ow/openwrt/trunk/staging_dir/target-mips_r2_uClibc-0.9.32/lib
-L/ow/openwrt/trunk/staging_dir/toolchain-mips_r2_gcc-linaro_uClibc-0.9.32/usr/lib
-L/ow/openwrt/trunk/staging_dir/toolchain-mips_r2_gcc-linaro_uClibc-0.9.32/lib
-Wl,--gc-sections
'
alias mgcc=$(echo $gcc_cmd)

usage:
$ source ./rt_gcc.sh
$ mgcc -o hello hello.c

标签:

我的openwrt配置

八 13th, 2011

路由器: tp-link wr841n (v7)
优点:11n路由器,信号不错,价格便宜。
缺点:空间较小,只有4M。刷openwrt是没有图形配置界面了,只能手动ssh配置。

刷openwrt:

http://downloads.openwrt.org/snapshots/trunk/ar71xx/openwrt-ar71xx-generic-tl-wr841nd-v7-squashfs-factory.bin

配置记录:
1. 安装必要的工具diff,pstree,以方便改设置和检查。
# opkg update
# rm -f /usr/bin/cmp
# opkg install diffutils
# opkg install psmisc
弄完后,把diff和pstree备份,
# opkg remove psmisc diffutils
然后把备份还原。没有办法,路由器空间较少。

2. 安装拨vpn所需组件:
# opkg install pptp mppe kmod-ipt-nathelper-extra
其中,前两个是保证路由器上能拔VPN(PPTP)。
最后一个是使接入的设备也能拨,这个说起来容易,但出事的时候很难知道是缺了哪个包。
仔细google来google去看了很多页面才偶然找到。

3. 配置网络
配置文件/etc/config/network
配置拔号:
config interface wan
option ifname eth1
option proto pppoe
option username xxxxx@163.xx
option password PASSWORD
option peerdns 1
配置VPN:
config interface vpn
option ifname pptp-vpn
option proto pptp
option username the_username
option password the_password
option server 74.117.x.x
option defaultroute 0
编辑/etc/ppp/options.pptp 删除其中的 defaultroute

4. 配置路由,使得不同的IP可以走VPN出口,也可以走默认的pppoe拔号出口。
修改 /etc/firewall
config zone
option name wan
list network ‘wan’
list network ‘vpn’

5. 配置dns, 使得*.google.com为某个固定IP,然后这个IP走VPN出口,防止google被河蟹。
编辑 /etc/dnsmasq.conf
address=/.google.com/74.125.153.106
编辑 /etc/config/network
config route
option interface vpn
option target 8.8.0.0
option netmask 255.255.0.0

config route
option interface vpn
option target 74.125.153.0
option netmask 255.255.255.0
由于google一个IP可以实现所有服务,因此这样配置是可以的。搜索,邮件啥的都不会有事。

6. 加速app store下载:
在/etc/hosts中:
203.69.113.238 itunes.apple.com
203.69.113.137 ax.init.itunes.apple.com
203.69.113.174 ax.su.itunes.apple.com

在 /etc/dnsmasq.conf 中:
address=/.phobos.apple.com/203.69.113.128

7. 使twitter和facebook的IP解析不被河蟹:
在/etc/dnsmasq.conf中:
server=/.facebook.com/8.8.8.8
server=/.twitter.com/8.8.8.8
注意前面已经设置了8.8.*.*走VPN出口,不担心它本身被河蟹。
暂时没时间进一步配置使它们解析后的地址走VPN了,反正已经不上了。
不过用类似前面GOOGLE的方式可以做到,只是要多写一些IP地址。

8. 增加一个普通用户,配置外部网SSH连接:
add @ /etc/shells
/bin/false
add @ /etc/passwd:
test1:*:1001:1001:test1:/home/test1:/bin/false
add @ /etc/group:
test1:x:1001:

#mkdir -p /home/test1/.ssh
#chown test1.test1 /home/test1
#chown test1.test1 /home/test1/.ssh
#chmod 0700 /home/test1
#chmod 0700 /home/test1/.ssh
#cp some-id-file.pub /home/test1/.ssh/authorized_keys
#chown test1.test1 /home/test1/.ssh/authorized_keys
#chmod 0600 /home/test1/.ssh/authorized_keys

add @ /etc/firewall
config redirect
option src wan
option src_dport 220
option dest lan
option dest_port 22
option proto tcp

9. 安装简单http服务器,使得可以看一些基本信息,并承载proxy.pac
#opkg install uhttpd
#/etc/init.d/uhttpd start
#cd /www
/www# ln -s /var/dhcp.leases dhcp.leases.txt
/www# vim proxy.pac

标签:

a simple script to prevent bricking for openwrt

八 12th, 2011
root@OpenWrt:~# cat /etc/init.d/unbrick 
#!/bin/sh /etc/rc.common
 
START=20
 
bakcat() {
	for i in $* ; do
		echo "################file seperator for $i##################"
		cat $i
		echo
	done
}
 
revert() {
	echo revert config...
	bakcat /etc/config/* >/root/cfgbak.all 2>&1
	cp -R /root/cfgbak/* /etc/config/
}
 
start() {
	count=$(cat /root/count_file)
	if [ $count -eq 0 ] ; then
		revert
	fi
	count=$((count-1))
	echo $count > /root/count_file
}
 
root@OpenWrt:~# /etc/init.d/unbrick enable
root@OpenWrt:~# echo 3 >  /root/count_file 
root@OpenWrt:~# mkdir /root/cfgbak

before modifying files in /etc/config, put an usable copy in /root/cfgbak.
if the script can run perfectly, echo 3 > /root/count_file after every reboot.
disable this script if the config files are valid and need no more change.
if any config file is wrong, reboot 3 times to unblick.

标签: