一、前言

我目前在开发的一款嵌入式产品,运行Linux系统,需要产品支持接入以太网后自动获取IP地址功能,写下此文记录实现的过程。

二、固定IP地址

产品前期调试,为了方便直接通过ifconfig命令设置产品IP为固定IP,例如:

ifconfig eth0 down
ifconfig eth0 192.168.1.100
ifcofnig eth0 up

产品成熟后,需通过DCHP让产品自动获取动态IP地址。

三、DHCP

DHCP全称是:动态主机设置协议(英语:Dynamic Host Configuration Protocol,DHCP)它是一个局域网的网络协议,使用 UDP 协议工作,主要有两个用途:

1)用于内部网或网络服务供应商自动分配 IP 地址;
2)给用户用于内部网管理员作为对所有计算机作中央管理的手段。
 

DHCP分为服务器端和客户端,通常是客户端向服务端申请地址,嵌入式产品上运行的一般是DCHP客户端。

四、UDHCPC

udhcpc是一个面向嵌入式系统的非常小的DHCP客户端,它通常由busybox支持。若文件系统内没有包含这个工具,需在busybox配置选项中开启,并重新编译busybox固件。udhcpc的典型用法举例:

udhcpc -i eth0 -s /etc/udhcpc.script -b

其中,

-i 是指定网卡,我这里只有一个eth0,有多个网卡时需要注意区分;

-s 是指定发生dhcp事件时运行的脚本,默认是/usr/share/udhcpc/default.script这个路径,我这里是将/etc/udhcpc.script软链到了默认路径。

-b 是指定切换到后台指令。

这里运行udhcpc的结果仅仅是从服务端拿到了合法的IP地址而已,还需要将IP、网关、DNS等写入网卡,才能正常使用网络。而这些动作全都由/usr/share/udhcpc/default.script这个脚本实现。这个脚本可以从\busybox-1.1.2\examples\udhcp下获取,将脚本simple.script重命名为default.script,放在开发板上的/usr/share/dhcpc/目录下。

下面是我的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"

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 "$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 rfc3359 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
Logo

更多推荐