如何阻止dnsmasq发送DHCPACK以测试esp8266的DHCP响应行为?
测试方案实现步骤
方案1:使用iptables直接拦截指定DHCPACK报文(最简便,无需修改dnsmasq配置)
- 首先确认目标esp8266的MAC地址,假设为
aa:bb:cc:dd:ee:ff。DHCPACK属于UDP协议,服务端源端口为67,客户端目标端口为68,且DHCP报文类型字段值为5对应该类型报文。 - 在树莓派上执行以下命令添加iptables规则,拦截发往该esp8266的DHCPACK报文:
sudo iptables -A OUTPUT -p udp --sport 67 --dport 68 -m mac --mac-destination aa:bb:cc:dd:ee:ff -m u32 --u32 "0x8 & 0xFF = 5" -j DROP
规则解释:匹配所有从DHCP服务端端口67发往客户端端口68、目标MAC为指定esp8266地址、DHCP报文类型为ACK的出站包,直接丢弃。
- 后续使用
tcpdump抓包观察esp8266的行为即可,抓包命令参考:
sudo tcpdump -i wlan0 port 67 or port 68 -vvv
注意将wlan0替换为你实际组网使用的网卡接口(如eth0等),之后重启esp8266触发DHCP流程,就能直接观察到它在收不到ACK时的报文发送逻辑。
- 测试完成后执行
sudo iptables -F清空添加的拦截规则,即可恢复正常DHCP服务。
方案2:使用scapy简化实现模拟DHCP服务
如果不想修改系统防火墙规则,也可以用scapy库实现极简DHCP服务逻辑,只响应DHCPDISCOVER返回OFFER、收到DHCPREQUEST后不做任何回复,刚好匹配测试需求,无需实现完整DHCP服务逻辑,核心代码参考:
from scapy.all import * # 替换为你实际的网卡接口、树莓派IP、要分配给esp8266的测试IP IFACE = "wlan0" SERVER_IP = "192.168.1.100" OFFER_IP = "192.168.1.120" def handle_dhcp(pkt): if DHCP in pkt and pkt[DHCP].options[0][1] == 1: # 收到DHCPDISCOVER,返回DHCPOFFER offer = Ether(dst=pkt[Ether].src)/IP(src=SERVER_IP, dst="255.255.255.255")/UDP(sport=67, dport=68)/BOOTP(op=2, yiaddr=OFFER_IP, siaddr=SERVER_IP, chaddr=pkt[BOOTP].chaddr, xid=pkt[BOOTP].xid)/DHCP(options=[("message-type", "offer"), ("server_id", SERVER_IP), ("lease_time", 86400), ("subnet_mask", "255.255.255.0"), ("router", SERVER_IP), "end"]) sendp(offer, iface=IFACE, verbose=0) elif DHCP in pkt and pkt[DHCP].options[0][1] == 3: # 收到DHCPREQUEST,直接丢弃不返回ACK,触发测试场景 pass # 运行前先停止本机dnsmasq服务避免端口冲突 sniff(filter="udp and (port 67 or 68)", prn=handle_dhcp, iface=IFACE)
内容的提问来源于stack exchange,提问作者vishnu m c
相关产品推荐
相关产品推荐

