Buildroot下dhcpd使用简介
关键词:dhcp、relay、config_packet、dhcpd.conf等。
DHCP(Dynamic Host Configuration Protocol)指的是由服务器控制一段IP地址范围,客户机登录服务器时就可以自动获得服务器分配的IP地址和子网掩码。担任DHCP服务器的计算机需要安装TCP/IP协议,并为其设置静态IP地址、子网掩码、默认网关等内容。
1 Buildroot/Linux kernel相关配置
dhcp需要支持Packet Socket,配置内核:
Networking support ->Network options ->Packet socket
Buildroot中打开dhcp server配置:
Target packages
->Networking applications
->dhcp (ISC)--ISC提供的开源DHCP服务器。 ->dhcp server-- ->Enable delayed ACK feature-- ->Enable paranoia options--提供额外的-user/-group/-chroot选项。 ->dhcp relay-- ->dhcp client--
DHCP Relay(DHCPR)DHCP中继(也叫做DHCP中继代理)是一个小程序,其可以实现在不同子网和物理网段之间处理和转发dhcp信息的功能。
如果DHCP客户机与DHCP服务器在同一个物理网段,则客户机可以正确地获得动态分配的ip地址。如果不在同一个物理网段,则需要DHCP Relay Agent(中继代理)。
用DHCP Relay代理可以去掉在每个物理的网段都要有DHCP服务器的必要,它可以传递消息到不在同一个物理子网的DHCP服务器,也可以将服务器的消息传回给不在同一个物理子网的DHCP客户机。
2 Buildroot下dhcp服务框架
S80dhcp-server作为启动dhcpd的入口,维护dhcpd的启停。
2.1 dhcpd框架
dhcpd从dhcpd.conf读取配置,pid存于dhcpd.pid,日志存于根据syslog.conf存放,IP分配记录存于dhcpd.leases。
dhcpd:DHCP守护进程,关于dhcpd详细说明《ISC DHCP 4.4 Manual Pages - dhcpd》。
dhcreplay:DHCP Relay守护进程。待跟进。
libdhcp.so:库文件。
libdhcpctl.so:库文件。
/etc/dhcp/dhcpd.conf:dhcpd的配置文件,关于dhcpd.conf详细说明《ISC DHCP 4.4 Manual Pages - dhcpd.conf》。
/etc/init.d/S80dpcp-server:rcS调用启动dhcpd守护进程。
/etc/init.d/S80dhcp-relay:启动DHCP Relay守护进程。
/run/dhcpd.pid:dhcpd守护进程的ID号。
/tmp/dhcpd.leases:保存dhcpd成功分IP服务的记录,更多参考《ISC DHCP 4.4 Manual Pages - dhcpd.leases》。
/var/log/messages:作为local7保存dhcpd运行日志。
2.2 DHCP Server和DCHP Client交互流程
如下是DHCP消息的说明:
报文类型 | 方向 | 说明 |
---|---|---|
Discover(0x01) | Client->Server | DHCP客户端在请求IP地址时并不知道DHCP服务器的位置,因此DHCP客户端会在本地网络内以广播方式发送Discover请求报文,以发现网络中的DHCP服务器。所有收到Discover报文的DHCP服务器都会发送应答报文,DHCP客户端据此可以知道网络中存在的DHCP服务器的位置。 |
Offer(0x02) | Server->Client | DHCP服务器收到Discover报文后,就会在所配置的地址池中查找一个合适的IP地址,加上相应的租约期限和其他配置信息(如网关、DNS服务器等),构造一个Offer报文,发送给DHCP客户端,告知用户本服务器可以为其提供IP地址。但这个报文只是告诉DHCP客户端可以提供IP地址,最终还需要客户端通过ARP来检测该IP地址是否重复。 |
Request(0x03) | Client->Server | DHCP客户端可能会收到很多Offer请求报文,所以必须在这些应答中选择一个。通常是选择第一个Offer应答报文的服务器作为自己的目标服务器,并向该服务器发送一个广播的Request请求报文,通告选择的服务器,希望获得所分配的IP地址。另外,DHCP客户端在成功获取IP地址后,在地址使用租期达到50%时,会向DHCP服务器发送单播Request请求报文请求续延租约,如果没有收到ACK报文,在租期达到87.5%时,会再次发送广播的Request请求报文以请求续延租约。 |
ACK(0x05) | Server->Client | DHCP服务器收到Request请求报文后,根据Request报文中携带的用户MAC来查找有没有相应的租约记录,如果有则发送ACK应答报文,通知用户可以使用分配的IP地址。 |
NAK(0x06) | Server->Client | 如果DHCP服务器收到Request请求报文后,没有发现有相应的租约记录或者由于某些原因无法正常分配IP地址,则向DHCP客户端发送NAK应答报文,通知用户无法分配合适的IP地址。 |
Release(0x07) | Client->Server | 当DHCP客户端不再需要使用分配IP地址时(一般出现在客户端关机、下线等状况)就会主动向DHCP服务器发送RELEASE请求报文,告知服务器用户不再需要分配IP地址,请求DHCP服务器释放对应的IP地址。 |
Decline(0x04) | Client->Server | DHCP客户端收到DHCP服务器ACK应答报文后,通过地址冲突检测发现服务器分配的地址冲突或者由于其他原因导致不能使用,则会向DHCP服务器发送Decline请求报文,通知服务器所分配的IP地址不可用,以期获得新的IP地址。 |
Inform(0x08) | Client->Server | DHCP客户端如果需要从DHCP服务器端获取更为详细的配置信息,则向DHCP服务器发送Inform请求报文;DHCP服务器在收到该报文后,将根据租约进行查找到相应的配置信息后,向DHCP客户端发送ACK应答报文。目前基本上不用了。 |
LEASEQUERY(0x0A) | Client->Server | 允许一个代理根据需要重新获得这种信息,它通常发生在一个中继流量已失去绑定的情况下。 |
LEASEUNASSIGNED(0x0B) | Server->Client | 该消息用于指出查询值得响应服务器是授权得,但目前没有分配相应租约。 |
LEASEUNKNOWN(0x0C) | Server->Client | 服务器最后一次询问客户机的时间(以秒为单位)。 |
LEASEACTIVE(0x0D) | Server->Client | 表示一个租约是有效的,并提供了租约参数(包括Tl和T2)。 |
一个典型DHCP交互流程如下:
2.3 dhcpd代码流程
dhcpd的主要代码如下:
main(dhcpd.c)
->dhcp_context_create
->omapi_init--Object Management Application Programming Interface。
->dhcp_interface_setup_hook
->db_startup
->discover_interfaces
->dhcp_interface_setup_hook
->dhcpd_interface_setup_hook
->omapi_register_io_object--收包处理交由got_one(AF_INET)/got_one_v6(AF_INET6)处理。
->got_one
->bootp_packet_handler
->do_packet
->packet_allocate--分配一个struct dhcp_packet。
->validate_packet--对packet进行有效性检查。
->dhcp--如果packet是DHCP类型,则调用dhcp()进行处理。根据packet_type进行处理。
->DHCPDISCOVER--DHCP Client在本地网络内以广播方式发送Discover请求报文,以发现网络DHCP Server。
->dhcpdiscover
->DHCPREQUEST--DHCP Client在收到Offer后,选择一个并发送Request请求报文给DHCP Server。
->dhcprequest
->DHCPRELEASE--DHCP Client不需要使用IP地址后,发送Release请求报文让DHCP Server释放IP地址。
->dhcprelease
->DHCPDECLINE--DHCP Client发现分配的地址不可用,则向Server发送Decline请求报文。
->dhcpdecline
->DHCPINFORM--为获取详细配置信息,DHCP Client向Server发送Inform请求报文。
->dhcpinform
->DHCPLEASEQUERY
->dhcpleasequery
->bootp--如果packet是BOOTP类型,则调用bootp()进行处理。
->got_one_v6
->dhcpv6_packet_handler
->do_packet6
3 DHCP服务器配置
3.1 S80dhcp-server
S80dhcp-server启动dhcpd守护进程:
#!/bin/sh # # $Id: dhcp3-server.init.d,v 1.4 2003/07/13 19:12:41 mdz Exp $ # # On what interfaces should the DHCP server (dhcpd) serve DHCP requests? # Separate multiple interfaces with spaces, e.g. "eth0 eth1". INTERFACES="usb0 usb1 usb2 usb3"--配置dhcpd管理的网络接口。 # Additional options that are passed to the DHCP server daemon? OPTIONS="" NAME="dhcpd" DAEMON="/usr/sbin/${NAME}" CFG_FILE="/etc/default/${NAME}" # Read configuration variable file if it is present [ -r "${CFG_FILE}" ] && . "${CFG_FILE}" # Sanity checks--判断dhcpd和dhcpd.conf是否存在,否则退出。 test -f /usr/sbin/dhcpd || exit 0 test -f /etc/dhcp/dhcpd.conf || exit 0 case "$1" in start) printf "Starting DHCP server: " test -d /var/lib/dhcp/ || mkdir -p /var/lib/dhcp/ test -f /var/lib/dhcp/dhcpd.leases || touch /var/lib/dhcp/dhcpd.leases start-stop-daemon -S -q -x ${DAEMON} -- -q $OPTIONS $INTERFACES--启动dhcpd守护进程。 [ $? = 0 ] && echo "OK" || echo "FAIL" ;; stop) printf "Stopping DHCP server: " start-stop-daemon -K -q -x ${DAEMON} [ $? = 0 ] && echo "OK" || echo "FAIL" ;; restart | force-reload) $0 stop $0 start if [ "$?" != "0" ]; then exit 1 fi ;; *) echo "Usage: $0 {start|stop|restart|force-reload}" exit 1 esac exit 0
3.2 /etc/dhcp/dhcp.conf
配置对应S80dhcp-server中INTERFACES的subnet IP地址范围:
# The ddns-updates-style parameter controls whether or not the server will # attempt to do a DNS update when a lease is confirmed. We default to the # behavior of the version 2 packages ('none', since DHCP v2 didn't # have support for DDNS.) ddns-update-style none; # option definitions common to all supported networks... option domain-name "example.org"; option domain-name-servers ns1.example.org, ns2.example.org; default-lease-time 600; max-lease-time 7200; # If this DHCP server is the official DHCP server for the local # network, the authoritative directive should be uncommented. authoritative;--使用正式版本dhcpd,可以打开此选项。 # Use this to send dhcp log messages to a different log file (you also # have to hack syslog.conf to complete the redirection). log-facility local7;--作为local7 facility输出到syslog.conf指定的log文件中。 # No service will be given on this subnet, but declaring it helps the # DHCP server to understand the network topology. subnet 192.168.11.0 netmask 255.255.255.0 {
range 192.168.11.3 192.168.11.255 }
subnet 192.168.22.0 netmask 255.255.255.0 {
range 192.168.22.3 192.168.22.255
}
subnet 192.168.33.0 netmask 255.255.255.0 {
range 192.168.33.3 192.168.33.255
}
subnet 192.168.44.0 netmask 255.255.255.0 {
range 192.168.44.3 192.168.44.255
}