You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何从最后一个DHCP Discover包提取XID以生成DHCP Offer

解决DHCP Discover报文XID提取问题

你的代码存在两个核心问题:未筛选DHCP Discover报文(会抓到Offer、Request等其他DHCP包),且没有确保取到的是最后一个Discover的XID。以下是修正方案:

方案1:抓取所有Discover后取最后一个的XID

这种方式适合需要一次性抓取并处理的场景:

from scapy.all import sniff, BOOTP, DHCP

# 筛选DHCP Discover报文:DHCP选项53的值为1(代表Discover类型)
def is_dhcp_discover(packet):
    return BOOTP in packet and DHCP in packet and \
           any(opt[0] == 53 and opt[1] == b'\x01' for opt in packet[DHCP].options)

# 抓取eth1接口上的所有DHCP Discover报文
packets = sniff(filter="udp and (port 67 or port 68)", iface="eth1", lfilter=is_dhcp_discover)

# 提取最后一个Discover的XID
if packets:
    last_xid = packets[-1][BOOTP].xid
    print(f"最后一个DHCP Discover的XID: {last_xid}")
else:
    print("未捕获到DHCP Discover报文")

方案2:实时更新最新Discover的XID(节省内存)

如果客户端持续发送Discover,这种方式可以实时保留最新的XID,无需存储所有报文:

from scapy.all import sniff, BOOTP, DHCP

latest_xid = None

def update_latest_xid(packet):
    global latest_xid
    # 检查是否为DHCP Discover报文
    if BOOTP in packet and DHCP in packet:
        for opt in packet[DHCP].options:
            if opt[0] == 53 and opt[1] == b'\x01':
                latest_xid = packet[BOOTP].xid
                print(f"最新Discover的XID已更新为: {latest_xid}")

# 持续抓取报文(按Ctrl+C停止),store=0表示不存储报文,节省内存
sniff(filter="udp and (port 67 or port 68)", iface="eth1", prn=update_latest_xid, store=0)

# 停止抓取后输出最终的最新XID
if latest_xid is not None:
    print(f"最终获取的最后一个DHCP Discover XID: {latest_xid}")
else:
    print("未捕获到DHCP Discover报文")

关键说明

  • DHCP报文类型由选项字段(编号53)标识:1=Discover,2=Offer,3=Request等,必须精准筛选才能拿到目标报文
  • 原代码未过滤报文类型,会导致XID可能来自非Discover报文,逻辑错误
  • 两种方案都加入了BOOTP/DHCP层存在性检查,避免因无效包引发异常

内容的提问来源于stack exchange,提问作者Ghofrane

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.29 18:03:11