【Linux应用】udhcpc命令获取到ip后,但是没有生效(没有设置进去)

今天遇到一个很奇葩的问题,udhcpc获取到了,但是ifconfig命令查看时却没有生效。下面来看下是怎么回事。


udhcpc是集成在busybox里面的,所以在编译busybox的时候加入dhcp的选项就可以了。

如果没有udhcpc的执行文件,可以手动连接一个:ln -s /bin/busybox  /sbin/udhcpc。

1、命令执行打印

# 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.0
          inet6 addr: fe80::31:a2ff:fe6d:75bf/64 Scope:Link
          UP BROADCAST RUNNING MULTICAST  MTU:1500  Metric:1
          RX packets:1451 errors:0 dropped:27 overruns:0 frame:0
          TX packets:24 errors:0 dropped:0 overruns:0 carrier:0
          collisions: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.0
          inet6 addr: ::1/128 Scope:Host
          UP LOOPBACK RUNNING  MTU:65536  Metric:1
          RX packets:0 errors:0 dropped:0 overruns:0 frame:0
          TX packets:0 errors:0 dropped:0 overruns:0 carrier:0
          collisions:0 txqueuelen:1 
          RX bytes:0 (0.0 B)  TX bytes:0 (0.0 B)

上面ifconfig命令打印出来的eth0网卡IP地址却不是172.30.15.20。说明我们虽然获取到了ip地址但是没有设置进去。

2、解决方案

通过搜索博客知道是: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)脚本文件。

3、udhcpc命令

从下面可以看到 -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 lease
        USR2    Release lease

4、解决方案

方案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/是可读可写文件,不需要编译时就生成。但是掉电就没有了,每次都需要应用程序去写一次,并且不能共用。

所以按需采用。

5、脚本

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"
[ -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}" ]; then
        IF_WAIT_DELAY=10
fi

wait_for_ipv6_default_route() {
        printf "Waiting for IPv6 default route to appear"
        while [ $IF_WAIT_DELAY -gt 0 ]; do
                if [ -z "$(ip -6 route list | grep default)" ]; then
                        printf "\n"
                        return
                fi
                sleep 1
                printf "."
                : $((IF_WAIT_DELAY -= 1))
        done
        printf " timeout!\n"
}

case "$1" in
        deconfig)
                /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 care
                TMPFILE=$(mktemp)
                grep -vE "# $interface\$" $RESOLV_CONF > $TMPFILE
                cat $TMPFILE > $RESOLV_CONF
                rm -f $TMPFILE

                if [ -x /usr/sbin/avahi-autoipd ]; then
                        /usr/sbin/avahi-autoipd -k $interface
                fi
                ;;

        leasefail|nak)
                if [ -x /usr/sbin/avahi-autoipd ]; then
                        /usr/sbin/avahi-autoipd -wD $interface --no-chroot
                fi
                ;;

        renew|bound)
                if [ -x /usr/sbin/avahi-autoipd ]; then
                        /usr/sbin/avahi-autoipd -k $interface
                fi
                /sbin/ifconfig $interface $ip $BROADCAST $NETMASK
                if [ -n "$ipv6" ] ; then
                        wait_for_ipv6_default_route
                fi

                if [ -n "$router" ] ; then
                        echo "deleting routers"
                        while route del default gw 0.0.0.0 dev $interface 2> /dev/null; do
                                :
                        done

                        for i in $router ; do
                                route add default gw $i dev $interface
                        done
                fi

                # drop info from this interface
                # resolv.conf may be a symlink to /tmp/, so take care
                TMPFILE=$(mktemp)
                grep -vE "# $interface\$" $RESOLV_CONF > $TMPFILE
                cat $TMPFILE > $RESOLV_CONF
                rm -f $TMPFILE

                # prefer rfc3397 domain search list (option 119) if available
                if [ -n "$search" ]; then
                        search_list=$search
                elif [ -n "$domain" ]; then
                        search_list=$domain
                fi

                [ -n "$search_list" ] &&
                        echo "search $search_list # $interface" >> $RESOLV_CONF

                for i in $dns ; do
                        echo adding dns $i
                        echo "nameserver $i # $interface" >> $RESOLV_CONF
                done
                ;;
esac

HOOK_DIR="$0.d"
for hook in "${HOOK_DIR}/"*; do
    [ -f "${hook}" -a -x "${hook}" ] || continue
    "${hook}" "${@}"
done

exit 0

再来一个

#!/bin/sh
# udhcpc script edited by Tim Riker <Tim@Rikers.org>

RESOLV_CONF="/etc/resolv.conf"

[ -n "$1" ] || { echo "Error: should be called from udhcpc"; exit 1; }

NETMASK=""
[ -n "$subnet" ] && NETMASK="netmask $subnet"
BROADCAST="broadcast +"
[ -n "$broadcast" ] && BROADCAST="broadcast $broadcast"

case "$1" in
        deconfig)
                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 $BROADCAST

                if [ -n "$router" ] ; then
                        echo "Deleting routers"
                        while busybox route del default gw 0.0.0.0 dev $interface ; do
                                :
                        done

                        metric=0
                        for i in $router ; do
                                echo "Adding router $i"
                                busybox route add default gw $i dev $interface metric $metric
                                : $(( metric += 1 ))
                        done
                fi

                echo "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 ; do
                        echo " Adding DNS server $i"
                        echo "nameserver $i" >> "$tmpfile"
                done
                busybox mv "$tmpfile" "$realconf"
                ;;
esac

exit 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

 

  • 15
    点赞
  • 55
    收藏
    觉得还不错? 一键收藏
  • 3
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值