问题现象
设备里的http server运行了CGI,在设置eth0为DHCP之后,怎么也没有默认路由信息。CGI调用的脚本最终是使用udhcpc,在shell里手工运行udhcpc总是能够自动设置默认路由。
问题解决
这个小小问题折腾了近两个小时!
从现象看,应该在手工运行udhcpc和CGI间接调用udhcpc之间差异着手。
一开始我的猜测是运行用户不同?CGI间接调用没有写路由权限?
后来发现不是这样。
好吧,看源码吧,好在udhcpc源码还算小巧,很快就看完了。
udhcpc创建RAW socket,广播discover并解析应答,收到应答之后运行/usr/share/udhcpc/default.script脚本设置IP、路由、DNS。
[root@ ~]# cat /usr/share/udhcpc/default.script
#!/bin/sh
# udhcpc script edited by Tim Riker <Tim@Rikers.org>
[ -z "$1" ] && echo "Error: should be called from udhcpc" && exit 1
RESOLV_CONF="/etc/resolv.conf"
[ -n "$broadcast" ] && BROADCAST="broadcast $broadcast"
[ -n "$subnet" ] && NETMASK="netmask $subnet"
case "$1" in
deconfig)
/sbin/ifconfig $interface 0.0.0.0
;;
renew|bound)
/sbin/ifconfig $interface $ip $BROADCAST $NETMASK
if [ -n "$router" ] ; then
echo "deleting routers"
while route del default gw 0.0.0.0 dev $interface ; do
:
done
for i in $router ; do
route add default gw $i dev $interface
done
fi
echo -n > $RESOLV_CONF
[ -n "$domain" ] && echo search $domain >> $RESOLV_CONF
for i in $dns ; do
echo adding dns $i
echo nameserver $i >> $RESOLV_CONF
done
;;
esac
exit 0
看出问题来了没?并没有!起码我没有。
跟踪到ps有/usr/share/udhcpc/default.script bound 进程,udhcpc里的RAW socket还是尽职尽责的,网关,DNS都获取到了,但为啥DNS设置了偏偏默认路由不设置!
当我把答案说出来,这问题就简单得令人发指了!
原因是route add default gw $i dev $interface这条命令根本没有运行,找不到route!在CGI运行环境里环境变量没有配置/sbin/
[root@ ~]# which ifconfig route
/sbin/ifconfig
/sbin/route
Tim Riker <Tim@Rikers.org>老人家是不是故意埋个坑^_^,ifconfig和route都是在/sbin下,偏偏ifconfig给带路径,route不带!我要写个邮件给他!
当然,其实这事不能怪人家。
好吧,udhcpc和udhcpd源码剖析,另文,先欠着。