from scapy.all import *
# 构造DHCP Discover包
def send_dhcp_discover():
# 1. 链路层:广播MAC
ether = Ether(dst="ff:ff:ff:ff:ff:ff", src=get_if_hwaddr(conf.iface))
# 2. 网络层:0.0.0.0 → 255.255.255.255
ip = IP(src="0.0.0.0", dst="255.255.255.255")
# 3. 传输层:UDP 68 → 67
udp = UDP(sport=68, dport=67)
# 4. BOOTP层:op=1(请求),chaddr为客户端MAC(自动获取)
bootp = BOOTP(op=1, chaddr=get_if_hwaddr(conf.iface))
# 5. DHCP层:message-type=1(Discover),请求参数
dhcp = DHCP(options=[
("message-type", "discover"), # 核心:Discover类型
("hostname", "test-client"), # 可选:客户端主机名
"end" # 必须:结束标记
])
# 组装并发送包
discover_pkt = ether / ip / udp / bootp / dhcp
sendp(discover_pkt, iface=conf.iface, verbose=1)
print("DHCP Discover包已发送!")
# 执行发送
if __name__ == "__main__":
send_dhcp_discover()
Offer
from scapy.all import *
def reply_dhcp(packet):
# 检查是否是DHCP Discover包
if DHCP in packet and packet[DHCP].options[0][1] == 1:
# 构造Offer包时指定分配的IP
assigned_ip = "192.168.1.100" # 预分配的IP
offer = Ether(dst=packet[Ether].src, src=get_if_hwaddr(conf.iface)) / \
IP(src="192.168.1.1", dst="255.255.255.255") / \
UDP(sport=67, dport=68) / \
BOOTP(op=2, yiaddr=assigned_ip, siaddr="192.168.1.1", chaddr=packet[BOOTP].chaddr) / \
DHCP(options=[("message-type", "offer"),
("server_id", "192.168.1.1"),
("subnet_mask", "255.255.255.0"),
("router", "192.168.1.1"),
"end"])
# 发送Offer包
sendp(offer, iface=conf.iface)
# 提取并打印分配的IP(两种方式,任选其一)
# 方式1:直接读取预定义的assigned_ip(简单)
print(f"已向客户端分配IP:{assigned_ip}")
# 方式2:从构造的Offer包中读取yiaddr(更严谨)
print(f"从Offer包中提取的分配IP:{offer[BOOTP].yiaddr}")
# 监听DHCP请求
sniff(filter="udp port 67 and udp port 68", prn=reply_dhcp)
浙公网安备 33010602011771号