Dnsmasq为小型网络提供网络基础设施:DNS,DHCP,路由器通告和网络引导。它被设计为轻量级且占用空间小,适用于资源受限的路由器和防火墙。它还被广泛用于智能手机和便携式热点的共享,并支持虚拟化框架中的虚拟网络。支持的平台包括Linux(带有glibc和uclibc),Android,* BSD和Mac OS X. Dnsmasq包含在大多数Linux发行版以及FreeBSD,OpenBSD和NetBSD的端口系统中。Dnsmasq提供完整的IPv6支持。
完整介绍请查看
dnsmasq详解&手册
两台EC20开发板,通过以太网口进行连接通讯,其中一台当服务端,另外一台当客户端并且由服务端分配ip。(用于模拟客户的Network Manager网络设备)
服务端使用dnsmasq这个工具来创建DHCP服务器。
部分参数简单说明:
-i, --interface=
指定接口监听。例如监听桥bridge0。
-I, --except-interface=
不要监听指定接口。不要监听lo回环接口。
-z, --bind-interfaces
设置dnsmasq只绑定监听接口。
–dhcp-range=
设置DHCP分配的地址范围
文档详细说明:
Man page of DNSMASQ
dhclient与udhcpc其实是同一个概念的东西,都是用来配置DHCP客户端。
Ubuntu系统使用dhclient进行配置,EC20开发板使用udhcpc进行配置。之前不了解,差点又要去移植dhclient,还好百度了一下。
udhcpc是一个面向嵌入式系统的非常小的DHCP客户端,字母的缩写微- DHCP -客户端(μDHCPc)。
/ # udhcpc -h
udhcpc: option requires an argument -- 'h'
BusyBox v1.23.1 (2019-02-28 19:55:01 CST) multi-call binary.
Usage: udhcpc [-fbqvRB] [-a[MSEC]] [-t N] [-T SEC] [-A SEC/-n]
[-i IFACE] [-P PORT] [-s PROG] [-p PIDFILE]
[-oC] [-r IP] [-V VENDOR] [-F NAME] [-x OPT:VAL]... [-O OPT]...
-i,--interface IFACE Interface to use (default eth0)
-P,--client-port PORT Use PORT (default 68)
-s,--script PROG Run PROG at DHCP events (default /usr/share/udhcpc/default.script)
-p,--pidfile FILE Create pidfile
-B,--broadcast Request broadcast replies
-t,--retries N Send up to N discover packets (default 3)
-T,--timeout SEC Pause between packets (default 3)
-A,--tryagain SEC Wait if lease is not obtained (default 20)
-n,--now Exit if lease is not obtained
-q,--quit Exit after obtaining lease
-R,--release Release IP on exit
-f,--foreground Run in foreground
-b,--background Background if lease is not obtained
-S,--syslog Log to syslog too
-a[MSEC],--arping[=MSEC] Validate offered address with ARP ping
-r,--request IP Request this IP address
-o,--no-default-options Don't request any options (unless -O is given)
-O,--request-option 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)
-F,--fqdn NAME Ask server to update DNS mapping for NAME
-V,--vendorclass VENDOR Vendor identifier (default 'udhcp VERSION')
-C,--clientid-none Don't send MAC as client identifier
-v Verbose
Signals:
USR1 Renew lease
USR2 Release lease
因开发板内部使用桥接的方式,因此udhcpc -i bridge0
/usrdata/grpc_test # udhcpc -i bridge0
udhcpc (v1.23.1) started
Sending discover...
Sending discover...
Sending discover...
Sending discover...
Sending discover...
Sending discover...
Sending discover...
Sending discover...
Sending discover...
Sending discover...
Sending select for 172.16.234.92...
Lease of 172.16.234.92 obtained, lease time 3600
开发板接受到DHCP服务器分配的IP。
但为啥ip没有修改成功能?
/usrdata/grpc_test # ifconfig
bridge0 Link encap:Ethernet HWaddr 1E:54:64:55:37:51
inet addr:172.16.234.25 Bcast:172.16.234.255 Mask:255.255.255.0
inet6 addr: fe80::1c54:64ff:fe52:344e/64 Scope:Link
UP BROADCAST RUNNING MULTICAST MTU:1500 Metric:1
RX packets:26 errors:0 dropped:0 overruns:0 frame:0
TX packets:37 errors:0 dropped:0 overruns:0 carrier:0
collisions:0 txqueuelen:0
RX bytes:1934 (1.8 KiB) TX bytes:6438 (6.2 KiB)
顺着参数选项udhcpc --script PROG。
开发板居然找不到这个脚本Run PROG at DHCP events (default /usr/share/udhcpc/default.script,后来上网查找资料后才发现原来在busybox源码中。
ARM-Linux配置DHCP自动获取IP地址
并将simple.script重命名为default.script,拷贝到开发板默认路径/usr/share/udhcpc。
实际测试ok。
/usrdata/grpc_test # udhcpc -i bridge0
udhcpc (v1.23.1) started
Setting IP address 0.0.0.0 on bridge0
Sending discover...
Sending select for 172.31.16.101...
Lease of 172.31.16.101 obtained, lease time 3600
Setting IP address 172.31.16.101 on bridge0
Deleting routers
route: SIOCDELRT: No such process
Adding router 172.31.16.26
Recreating /etc/resolv.conf
Adding DNS server 172.31.16.26
客户端设备自动分配的ip设置成功。
/usrdata/grpc_test # ifconfig
bridge0 Link encap:Ethernet HWaddr CA:A7:FD:4D:94:05
inet addr:172.31.16.101 Bcast:172.31.16.255 Mask:255.255.255.0
UP BROADCAST RUNNING MULTICAST MTU:1500 Metric:1
RX packets:21 errors:0 dropped:0 overruns:0 frame:0
TX packets:21 errors:0 dropped:0 overruns:0 carrier:0
collisions:0 txqueuelen:0
RX bytes:1618 (1.5 KiB) TX bytes:1492 (1.4 KiB)
为了省事,我把default.script脚本内容贴出来,后续只需保存成default.script文件即可。
#!/bin/sh
# udhcpc script edited by Tim Riker
RESOLV_CONF="/etc/resolv.conf"
[ -n "$1" ] || { echo "Error: should be called from udhcpc"; exit 1; }
NETMASK=""
if command -v ip >/dev/null; then
[ -n "$subnet" ] && NETMASK="/$subnet"
else
[ -n "$subnet" ] && NETMASK="netmask $subnet"
fi
BROADCAST="broadcast +"
[ -n "$broadcast" ] && BROADCAST="broadcast $broadcast"
case "$1" in
deconfig)
echo "Setting IP address 0.0.0.0 on $interface"
if command -v ip >/dev/null; then
ip addr flush dev $interface
else
ifconfig $interface 0.0.0.0
fi
;;
renew|bound)
echo "Setting IP address $ip on $interface"
if command -v ip >/dev/null; then
ip addr add $ip$NETMASK $BROADCAST dev $interface
else
ifconfig $interface $ip $NETMASK $BROADCAST
fi
if [ -n "$router" ] ; then
echo "Deleting routers"
while route del default gw 0.0.0.0 dev $interface ; do
:
done
metric=0
for i in $router ; do
echo "Adding router $i"
if [ "$subnet" = "255.255.255.255" ]; then
# special case for /32 subnets:
# /32 instructs kernel to always use routing for all outgoing packets
# (they can never be sent to local subnet - there is no local subnet for /32).
# Used in datacenters, avoids the need for private ip-addresses between two hops.
ip route add $i dev $interface
fi
route add default gw $i dev $interface metric $((metric++))
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.
if test -L "$RESOLV_CONF"; then
# If it's a dangling symlink, try to create the target.
test -e "$RESOLV_CONF" || touch "$RESOLV_CONF"
fi
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
mv "$tmpfile" "$realconf"
;;
esac
exit 0
vi /etc/dnsmasq.conf添加如下信息
# For debugging purposes, log each DNS query as it passes through
# dnsmasq.
log-queries
#log-facility=
log-facility=/var/log/dnsmasq.log
有点奇怪我如果不注释掉log-facility=,dnsmaq服务端则无法正常启动。
client端discover成功后,dnsmasq.log会记录client端设备的一些信息。
Jan 1 00:00:00 dnsmasq[996]: started, version 2.73 cachesize 150
Jan 1 00:00:00 dnsmasq[996]: compile time options: IPv6 GNU-getopt no-DBus no-i18n no-IDN DHCP DHCPv6 no-Lua TFTP no-conntrack ipset auth no-DNSSEC loop-detect inotify
Jan 1 00:00:00 dnsmasq-dhcp[996]: DHCP, IP range 10.0.0.10 -- 10.0.0.200, lease time 2h
Jan 1 00:00:00 dnsmasq-dhcp[996]: DHCP, IP range 192.168.1.1 -- 192.168.1.254, lease time 1h
Jan 1 00:00:00 dnsmasq-dhcp[996]: DHCP, sockets bound exclusively to interface bridge0
Jan 1 00:00:00 dnsmasq[996]: no servers found in /etc/resolv.conf, will retry
Jan 1 00:00:00 dnsmasq[996]: read /etc/hosts - 2 addresses
Jan 1 00:00:00 dnsmasq-dhcp[996]: read /etc/dhcp_hosts
Jan 1 00:00:23 dnsmasq[1902]: started, version 2.73 cachesize 150
Jan 1 00:00:23 dnsmasq[1902]: compile time options: IPv6 GNU-getopt no-DBus no-i18n no-IDN DHCP DHCPv6 no-Lua TFTP no-conntrack ipset auth no-DNSSEC loop-detect inotify
Jan 1 00:00:23 dnsmasq-dhcp[1902]: DHCP, IP range 10.0.0.10 -- 10.0.0.200, lease time 2h
Jan 1 00:00:23 dnsmasq-dhcp[1902]: DHCP, IP range 192.168.1.1 -- 192.168.1.254, lease time 1h
Jan 1 00:00:23 dnsmasq-dhcp[1902]: DHCP, sockets bound exclusively to interface bridge0
Jan 1 00:00:23 dnsmasq[1902]: no servers found in /etc/resolv.conf, will retry
Jan 1 00:00:23 dnsmasq[1902]: read /etc/hosts - 3 addresses
Jan 1 00:00:23 dnsmasq-dhcp[1902]: read /etc/dhcp_hosts
Jan 1 00:00:23 dnsmasq[1902]: reading /etc/resolv.conf
Jan 1 00:00:23 dnsmasq[1902]: using nameserver 183.230.126.225#53
Jan 1 00:00:23 dnsmasq[1902]: reading /etc/resolv.conf
Jan 1 00:00:23 dnsmasq[1902]: using nameserver 183.230.126.225#53
Jan 1 00:00:23 dnsmasq[1902]: using nameserver 183.230.126.224#53