最近遇到一个dhcp问题,因此将dhcp过程及涉及到的知识点进行了回炉学习,在这里简单做下总结
-----再牛逼的梦想,也抵不住傻逼般的坚持!
源码下载路径https://udhcp.busybox.net/
一、dhcp过程简单讲解
1.第一步:client 发送discover寻找dhcp server;
注:此处发送的包针对链路层来说是广播包。但是针对dhcp协议,需要通过bootp flags来区分是广播or单播包
2.第二步:server发送offer, offer报文中携带了分配的ip。
3.第三步:client发送request,携带server分配的ip.
4.第四步:server发送ack
上述过程为静电的正常dhcp过程,详细的过程可自行百度了解
这里主要讲述下dhcp遇到的问题及解决方法:
二、问题分析
问题1:路由器兼容性,部分路由dhcp失败
背景:dut设备在做路由器兼容性测试时发现,部分路由器设备配网一直失败。之后通过设备log及抓取空口包发现,设备在与路由链路层建立连接后,dhcp失败。
分析:
a.不同设备对比分析;尝试使用其他设备进行同样操作的连接,比如:手机、竞品设备,发现均能正常连接。
b.不通加密方式分析;尝试将路由器改为不加密状态, 再次进行测试。dhcp失败概率降低,但仍存在失败的情况。(该测试只为分析影响,即使改为不加密,dut设备能够完全正常连接,也不能说明是加密的问题)
c.空口包及设备tcpdump抓包分析; 通过设备tcpdump抓取的报文分析,发现设备一直在发送request及discover报文,路由器一直未做回复。(这里不能够因为是路由器不回复,就觉得是路由器问题,应该了解到根因,多问自己一下为什么其他的设备可以正常连接)
深入分析后发现如下两处异常:
异常一:dut设备在每次dhcp,都会先携带自身默认的ip发送request包。正常设备则是直接发起discover
异常二:dut设备发送discover及request时,均是使用广播的模式,即报文中bootp flags为0x8000。而正常设备则为单播,即bootp flags为0
通过如上异常点分析,并做了对应的修改验证,最终发现,dut设备dhcp失败,是由于发送dhcp包时使用了广播包的方式,部分路由器对此不支持。因此导致设备一直连接失败。
三、udhcpc & udhcpd交叉编译及问题处理
1.源码获取:
a)udhcpd/udhcpc:https://udhcp.busybox.net/source/ (本次交叉编译以udhcp-0.9.8.tar.gz演示)
2.交叉编译
make ARCH=arm CROSS_COMPILE=arm-linux-gnueabihf-gcc4.9.4-uclibc1.0.31-
3.交叉编译报错解决
a) 报错提示如下,该报错是由于交叉编译工具链版本过高导致判断dhcpc.c:134:7写法错误,修正即可
dhcpc.h:7:24: error: label at end of compound statement
#define INIT_SELECTING 0
^
dhcpc.c:134:7: note: in expansion of macro 'INIT_SELECTING'
case INIT_SELECTING:
b)其他报错遇到后再记录
四、udhcpc & udhcpd的使用
1)udhcpc的使用
udhcpc -i br0 &(网卡根据自己需要指定)
2)udhcpd使用方法
udhcpd udhcpd.conf &(conf文件根据自己需要修改,参考文件在源码路径udhcp-0.9.8\samples\udhcpd.conf)
DHCP server
-f Run in foreground
-S Log to syslog too
-P N Use port N (default 67)
3)udhcpd.conf配置说明
udhcpd.conf
interface wlan1 //指定网卡
start 192.168.102.103 //ip池首地址
end 192.168.102.254 //ip池尾地址
opt subnet 255.255.255.0 //掩码
opt router 192.168.102.1 //网关
opt lease 600 //ip租约时间,即ip有效期
remaining no //ip续约失败,将ip标记为“未使用”,以便重新分配给其他客户端
pidfile /var/tmp/udhcp.pid //pid路径
opt dns 8.8.8.8 //dns
opt dns 8.8.4.4 //dns
lease_file /mnt/mtd/Config/udhcpd.leases
max_leases 10 //最大连接数量
auto_time 600 //客户端自动请求新租约的时间间隔
echo “interface wlan1\nstart 192.168.102.103\nend 192.168.102.254\nopt subnet 255.255.255.0\nopt router 192.168.102.1\nopt lease 600\nremaining no\npidfile /var/tmp/udhcp.pid\nopt dns 8.8.8.8\nopt dns 8.8.4.4\nlease_file /mnt/mtd/Config/udhcpd.leases\nmax_leases 10\nauto_time 600” > /var/tmp/udhcpd.conf
使用过程中遇到的问题
问题1: udhcpc -i br0 &执行后,ifconfig未查询到ip,但路由器上能够正常看到设备
问题原因:udhcpc 依赖一个.script的脚本,在源码中可以找到(udhcp-0.9.8\samples\simple.script)将脚本打包进设备,并通过-s指定即可,udhcpc -i br0 -s simple.script &;脚本的作用可自行查询,或查看脚本内容即能明白
问题2: 出现Unable to open /var/lib/misc/udhcpd.leases for reading报错
问题原因:udhcpd.leases该文件,或文件所在路径仅有只读权限,或无该文件
解决方法:touch一个文件,并设置相应权限即可
问题3: 出现SIOCGIFADDR failed, is the interface up and configured?: Cannot assign requested address报错
原因:ap的网卡没有默认ip,设置默认ip后再运行udhcpd即可(默认ip与udhcpd.conf中的配置要匹配)
后续遇到与dhcp相关问题会持续在本文中更新