今天遇到一个很奇葩的问题,udhcpc获取到了,但是ifconfig命令查看时却没有生效。下面来看下是怎么回事。
udhcpc是集成在busybox里面的,所以在编译busybox的时候加入dhcp的选项就可以了。
如果没有udhcpc的执行文件,可以手动连接一个:ln -s /bin/busybox /sbin/udhcpc。
# udhcpc -b -i eth0
udhcpc: started, v1.31.1
udhcpc: sending discover
udhcpc: sending select for 172.30.15.20
udhcpc: lease of 172.30.15.20 obtained, lease time 691200
从上面打印可以明显得出结论,我们是获取到了ip地址的172.30.15.20,ip地址为。来看下ifconfig命令打印。
# udhcpc -b -i eth0
udhcpc: started, v1.31.1
udhcpc: sending discover
udhcpc: sending select for 172.30.15.20
udhcpc: lease of 172.30.15.20 obtained, lease time 691200
#
# ifconfig
eth0 Link encap:Ethernet HWaddr 02:31:A2:6D:75:BF inet addr:172.30.15.67 Bcast:172.30.255.255 Mask:255.255.0.0inet6 addr: fe80::31:a2ff:fe6d:75bf/64 Scope:LinkUP BROADCAST RUNNING MULTICAST MTU:1500 Metric:1RX packets:1451 errors:0 dropped:27 overruns:0 frame:0TX packets:24 errors:0 dropped:0 overruns:0 carrier:0collisions:0 txqueuelen:1000 RX bytes:624135 (609.5 KiB) TX bytes:3879 (3.7 KiB)Interrupt:41 lo Link encap:Local Loopback inet addr:127.0.0.1 Mask:255.0.0.0inet6 addr: ::1/128 Scope:HostUP LOOPBACK RUNNING MTU:65536 Metric:1RX packets:0 errors:0 dropped:0 overruns:0 frame:0TX packets:0 errors:0 dropped:0 overruns:0 carrier:0collisions:0 txqueuelen:1 RX bytes:0 (0.0 B) TX bytes:0 (0.0 B)
上面ifconfig命令打印出来的eth0网卡IP地址却不是172.30.15.20。说明我们虽然获取到了ip地址但是没有设置进去。
通过搜索博客知道是:udhcpc命令只能去获取到ip,但是不能设置。设置过程是(default.script)脚本来完成的。这个脚本默认位置在/usr/share/udhcpc/default.script。
参考博客:https://blog.csdn.net/sddsighhz/article/details/46005629
来看下我的这个路径:
# ls -l /usr/share/
total 0
drwxr-xr-x 4 root root 0 Jul 13 2020 alsa
发现并没有这个脚本文件。应该是被系统裁剪掉了。下面尝试补充这个脚本,发现这个路径是只读路径。没办法添加到默认路径中去,只有/tmp/路径是可读可写的,想办法让udhcpc命令去执行这个路径下的(default.script)脚本文件。
从下面可以看到 -s 传参可以指定这个脚本文件路径,到此我们就可以解决这个问题了。
# udhcpc -h
udhcpc: option requires an argument -- 'h'
BusyBox v1.31.1 (2020-07-13 19:33:08 CST) multi-call binary.Usage: udhcpc [-fbqRB] [-a[MSEC]] [-t N] [-T SEC] [-A SEC/-n][-i IFACE] [-s PROG] [-p PIDFILE][-oC] [-r IP] [-V VENDOR] [-F NAME] [-x OPT:VAL]... [-O OPT]...-i IFACE Interface to use (default eth0)-s PROG Run PROG at DHCP events (default /usr/share/udhcpc/default.script)-p FILE Create pidfile-B Request broadcast replies-t N Send up to N discover packets (default 3)-T SEC Pause between packets (default 3)-A SEC Wait if lease is not obtained (default 20)-b Background if lease is not obtained-n Exit if lease is not obtained-q Exit after obtaining lease-R Release IP on exit-f Run in foreground-S Log to syslog too-a[MSEC] Validate offered address with ARP ping-r IP Request this IP address-o Don't request any options (unless -O is given)-O OPT Request option OPT from server (cumulative)-x OPT:VAL Include option OPT in sent packets (cumulative)Examples of string, numeric, and hex byte opts:-x hostname:bbox - option 12-x lease:3600 - option 51 (lease time)-x 0x3d:0100BEEFC0FFEE - option 61 (client id)-x 14:'"dumpfile"' - option 14 (shell-quoted)-F NAME Ask server to update DNS mapping for NAME-V VENDOR Vendor identifier (default 'udhcp VERSION')-C Don't send MAC as client identifier
Signals:USR1 Renew leaseUSR2 Release lease
方案1:
1、在/usr/share/udhcpc/默认路径直接添加default.script文件
2、执行udhcpc命令(如:udhcpc -b -i eth0)
方案2:
1、在/tmp/路径下添加default.script文件
2、执行udhcpc命令,但是要带 -s 传参脚本路径(如:udhcpc -b -s /tmp/default.script -i eth0)
如:busybox udhcpc -b -q -t 1 -i eth0 -s /etc/simple.script -p /var/run/udhcpc.pid &
方案1:/usr/share/udhcpc/路径是只读文件,需要编译文件系统时就要编译进去。但是用起来比较方便,所有程序直接都能共用。
方案2:/tmp/是可读可写文件,不需要编译时就生成。但是掉电就没有了,每次都需要应用程序去写一次,并且不能共用。
所以按需采用。
default.script脚本如下:
#!/bin/sh# udhcpc script edited by Tim Riker
[ -e $RESOLV_CONF ] || touch $RESOLV_CONF
[ -n "$broadcast" ] && BROADCAST="broadcast $broadcast"
[ -n "$subnet" ] && NETMASK="netmask $subnet"
# Handle stateful DHCPv6 like DHCPv4
[ -n "$ipv6" ] && ip="$ipv6/128"if [ -z "${IF_WAIT_DELAY}" ]; thenIF_WAIT_DELAY=10
fiwait_for_ipv6_default_route() {printf "Waiting for IPv6 default route to appear"while [ $IF_WAIT_DELAY -gt 0 ]; doif [ -z "$(ip -6 route list | grep default)" ]; thenprintf "\n"returnfisleep 1printf ".": $((IF_WAIT_DELAY -= 1))doneprintf " timeout!\n"
}case "$1" indeconfig)/sbin/ifconfig $interface up/sbin/ifconfig $interface 0.0.0.0# drop info from this interface# resolv.conf may be a symlink to /tmp/, so take careTMPFILE=$(mktemp)grep -vE "# $interface\$" $RESOLV_CONF > $TMPFILEcat $TMPFILE > $RESOLV_CONFrm -f $TMPFILEif [ -x /usr/sbin/avahi-autoipd ]; then/usr/sbin/avahi-autoipd -k $interfacefi;;leasefail|nak)if [ -x /usr/sbin/avahi-autoipd ]; then/usr/sbin/avahi-autoipd -wD $interface --no-chrootfi;;renew|bound)if [ -x /usr/sbin/avahi-autoipd ]; then/usr/sbin/avahi-autoipd -k $interfacefi/sbin/ifconfig $interface $ip $BROADCAST $NETMASKif [ -n "$ipv6" ] ; thenwait_for_ipv6_default_routefiif [ -n "$router" ] ; thenecho "deleting routers"while route del default gw 0.0.0.0 dev $interface 2> /dev/null; do:donefor i in $router ; doroute add default gw $i dev $interfacedonefi# drop info from this interface# resolv.conf may be a symlink to /tmp/, so take careTMPFILE=$(mktemp)grep -vE "# $interface\$" $RESOLV_CONF > $TMPFILEcat $TMPFILE > $RESOLV_CONFrm -f $TMPFILE# prefer rfc3397 domain search list (option 119) if availableif [ -n "$search" ]; thensearch_list=$searchelif [ -n "$domain" ]; thensearch_list=$domainfi[ -n "$search_list" ] &&echo "search $search_list # $interface" >> $RESOLV_CONFfor i in $dns ; doecho adding dns $iecho "nameserver $i # $interface" >> $RESOLV_CONFdone;;
esacHOOK_DIR="$0.d"
for hook in "${HOOK_DIR}/"*; do[ -f "${hook}" -a -x "${hook}" ] || continue"${hook}" "${@}"
doneexit 0
再来一个
#!/bin/sh
# udhcpc script edited by Tim Riker
[ -n "$subnet" ] && NETMASK="netmask $subnet"
BROADCAST="broadcast +"
[ -n "$broadcast" ] && BROADCAST="broadcast $broadcast"case "$1" indeconfig)echo "Setting IP address 0.0.0.0 on $interface"busybox ifconfig $interface 0.0.0.0;;renew|bound)echo "Setting IP address $ip on $interface"busybox ifconfig $interface $ip $NETMASK $BROADCASTif [ -n "$router" ] ; thenecho "Deleting routers"while busybox route del default gw 0.0.0.0 dev $interface ; do:dOnemetric=0for i in $router ; doecho "Adding router $i"busybox route add default gw $i dev $interface metric $metric: $(( metric += 1 ))donefiecho "Recreating $RESOLV_CONF"# If the file is a symlink somewhere (like /etc/resolv.conf# pointing to /run/resolv.conf), make sure things work.realcOnf=$(readlink -f "$RESOLV_CONF" 2>/dev/null || echo "$RESOLV_CONF")tmpfile="$realconf-$$"> "$tmpfile"[ -n "$domain" ] && echo "search $domain" >> "$tmpfile"for i in $dns ; doecho " Adding DNS server $i"echo "nameserver $i" >> "$tmpfile"donebusybox mv "$tmpfile" "$realconf";;
esacexit 0
这个问题的原因是,udhcpc命令只能获取ip,设置ip是靠default.script脚本来完成的。
解决步骤:
1、创建default.script脚本
2、添加default.script脚本的权限为0755(这个很重要)
3、执行udhcpc命令(udhcpc -b -s /tmp/default.script -i eth0)
正常打印:
# udhcpc -b -s /tmp/default.script -i eth0
udhcpc: started, v1.31.1
udhcpc: sending discover
udhcpc: sending select for 172.30.15.20
udhcpc: lease of 172.30.15.20 obtained, lease time 691200
deleting routers
adding dns 202.96.134.133
adding dns 202.96.128.166