使用Python创建两段代码来模拟DHCP协议动态IP分配的过程。 我别无选择,只能选择DHCP 主题,因为互联网上没有太多信息,因为我之前遇到过课程实施。晚上我写了这段不完整但还过得去的代码。由于第二天就要录用,我没有时间做进一步的优化,所以还是通过了。在本文中,我们将仅模拟客户端的第一个请求。即,客户端发送发现广播消息,服务器以提供消息响应,客户端发送请求消息,服务器以ACK确认消息响应。您可以多次复制客户端代码来创建多个客户端。复制后无需更改每个客户端的MAC地址即可运行。代码中有一些冗余,但这主要用于调试。虽然这里只模拟了4条消息,但服务器始终监听端口并响应响应消息。学生自己需要此代码来验证他们的IP 地址。 DHCP消息可以通过抓包软件来捕获。这里我们使用Python第三方库scapy和Pycharm软件。服务器运行在单独的pycharm项目中,客户端运行单独的pycharm项目。如果您需要使用窗口显示,您可以自己创建一个。执行结果如下。
服务终端:
客户10:
客户端20:
服务器代码:
从scapy.all 导入*
随机导入
导入时间
从scapy.layers.dhcp 导入DHCP、BOOTP
从scapy.layers.inet 导入IP、UDP
从scapy.layers.l2 导入以太币
def build_dns_option(dns_servers):
””
为您的DNS 服务器手动构建DHCP 选项字节字符串
””
option_code=6 #domain_name_server 的DHCP 选项代码
option_data=b\’\’.join([socket.inet_aton(server) for server in dns_servers.split(\’,\’)])
option_length=len(option_data) + 1 #长度包括选项代码本身
返回字节数([选项代码])+字节数([选项长度])+选项数据
def response_to_dhcp_discover(pkt):
如果pkt 中的DHCP 和pkt[DHCP].options[0][1]==1:
client_mac=pkt[以太].src
print(f\’\\n发现请求,MAC地址为:{client_mac}\’)
client_ip=\’192.168.1.\’ + str(random.randint(100, 200)) #随机分配IP给客户端
global client_t_ip #定义一个全局变量来存储客户端的IP
客户端IP=客户端IP
dns_option=build_dns_option(\’8.8.8.8,8.8.4.4\’) #为DNS服务器构建DHCP选项的字节字符串
dhcp_offer=以太币(src=get_if_hwaddr(conf.iface), dst=client_mac)/\\
IP(src=\’192.168.1.1\’, dst=\’255.255.255.255\’)/\\
UDP(运动=67,d端口=68)/\\
BOOTP(op=2,chaddr=client_mac,yiaddr=client_ip)/\\
DHCP(选项=[
(\’消息类型\’, \’报价\’),
(\’服务器ID\’, \’192.168.1.1\’),
(\’租赁时间\’, 43200),
(\’子网掩码\’, \’255.255.255.0\’),
(\’路由器\’, \’192.168.1.1\’),
(b\’\\x06\’ + bytes([len(dns_option)]) + dns_option), # 添加DNS 服务器选项
(\’结尾\’)
])
sendp(dhcp_offer,详细=0)
print(f\’向: 客户端mac: {client_mac} 发送DHCP Offer,并随机分配客户端IP 为:{client_ip}\’)
print(\’DHCP 客户端可以提供IP 地址.\’)
def response_to_dhcp_request(pkt):
如果数据包中有DHCP 并且pkt[DHCP].options[0][1]==3:
print(\’找到请求请求消息\’)
request_ip=pkt[DHCP].options[2][1] #
client_mac=pkt[以太].src
print(f\’对方的MAC地址是:{client_mac}\’)
服务器ID=pkt[DHCP].options[2][1]
# print(f\’requested_ip{requested_ip}\\n\’)
print(f\’验证此服务器ID: {server_id}\’)
如果服务器ID==\’192.168.1.1\’:
dns_option=build_dns_option(\’8.8.8.8,8.8.4.4\’) # 为DNS 服务器构建DHCP 选项的字节字符串
# 打印(\’22222222222\’)
dhcp_ack=以太(src=get_if_hwaddr(conf.iface), dst=client_mac)/\\
IP(src=\’192.168.1.1\’, dst=\’255.255.255.255\’)/\\
UDP(运动=67,d端口=68)/\\
BOOTP(op=2,chaddr=client_mac,yiaddr=client_t_ip)/\\
DHCP(选项=[
(\’消息类型\’, \’ack\’),
(\’服务器ID\’,服务器ID),
(\’租赁时间\’, 43200),
(\’子网掩码\’, \’255.255.255.0\’),
(\’路由器\’, \’192.168.1.1\’),
(b\’\\x06\’ + bytes([len(dns_option)]) + dns_option), # 手动添加DNS 服务器选项
(\’结尾\’)
])
# 打印(\’33333333333\’)
发送(dhcp_ack,详细=0)
print(f\’将DHCP ACK 确认发送到IP {client_t_ip} 上的{client_mac}\’)
print(\’IP分配成功!\\n\\n\’)
# 同时监控并响应DISCOVER 和REQUEST 消息
同时(1):
filter_str=\’udp 和(端口67 或端口68)\’
嗅探(prn=lambda x: Reply_to_dhcp_discover(x)或Reply_to_dhcp_request(x),
filter=filter_str, store=0, iface=\’WLAN\’) #WLAN是网卡
客户端10代码:
从scapy.all 导入*
随机导入
导入时间
导入二进制密钥
从scapy.layers.dhcp 导入BOOTP、DHCP
从scapy.layers.inet 导入IP、UDP
从scapy.layers.l2 导入以太币
def send_dhcp_discover(接口=\’WLAN\’):
””
发送DHCP DISCOVER 消息
””
# 使用Binascii.hexlify 将MAC 地址字符串转换为原始字节
mac_bytes=binascii.unhexlify(\’00:11:22:33:44:55\’.replace(\’:\’, \’\’))#这里更改客户端的MAC地址
#global client_t_mac #定义一个全局变量来存储client_mac地址
#client_t_mac=mac_bytes
#print(f\’本地客户端mac是:{mac_bytes}\’)
dhcp_discover=以太(src=mac_bytes, dst=\’ff:ff:ff:ff:ff:ff\’) \\
/IP(src=\’0.0.0.0\’, dst=\’255.255.255.255\’) \\
/UDP(运动=68,d端口=67) \\
/BOOTP(chaddr=mac_bytes) \\
/DHCP(option=[(\’消息类型\’, \’检测\’), (\’终止\’)])
sendp(dhcp_discover, iface=接口, 详细=0)
print(\’客户端发送发现广播请求:src=\\\’0.0.0.0\\\’, dst=\\\’255.255.255.255\\\’\’)
def response_to_dhcp_offer(pkt):
””
响应收到的DHCP OFFER 消息
””
if DHCP in pkt and pkt[DHCP].options[0][1]==2: # 检查是否有DHCP OFFER 消息
server_id=pkt[DHCP].options[1][1] # 服务器ID
Offered_ip=pkt[BOOTP].yiaddr # 提供的IP地址
client_mac=pkt[Ether].src #客户端MAC地址
print(f\’确保与本地MAC地址相同:{client_mac}\’)
print(f\’客户端收到报价响应消息:服务器ID:{server_id}报价ip:{offered_ip}\’)
# 使用正确的方式处理MAC地址
mac_bytes=binascii.unhexlify(\’00:11:22:33:44:55\’.replace(\’:\’, \’\’))
# 构建DHCP REQUEST 消息
dhcp_request=以太(src=mac_bytes, dst=\’ff:ff:ff:ff:ff:ff\’)/\\
IP(src=\’0.0.0.0\’, dst=\’255.255.255.255\’)/\\
UDP(运动=68,d端口=67)/\\
BOOTP(chaddr=mac_bytes, yiaddr=offered_ip)/\\
DHCP(选项=[
(\’消息类型\’, \’请求\’),
(\’requested_addr\’,offered_ip),
(\’服务器ID\’,服务器ID),
(\’结尾\’)
])
sendp(dhcp_request,verbose=0) #发送DHCP REQUEST消息
print(f\’广播(请求)发送请求的IP地址到服务器:{offered_ip} server ip: {server_id}\’)
默认ack_ack(pkt):
如果数据包中有DHCP 并且pkt[DHCP].options[0][1]==5:
client_ip=pkt[BOOTP].yiaddr # 分配给客户端的IP地址
subnet_mask=next((opt[1] for opt in pkt[DHCP].options if opt[0]==\’subnet_mask\’), None) # 子网掩码
router_ip=next((opt[1] for opt in pkt[DHCP].options if opt[0]==\’router\’), None) #默认网关
dns_servers=[opt[1] for opt in pkt[DHCP].options if opt[0]==6] # DNS 服务器列表
print(f\’客户端收到DHCP ACK 数据包:\’)
print(f\’ – 分配的IP 地址: {client_ip}\’)
对于子网掩码:
print(f\’ – 子网掩码: {subnet_mask}\’)
对于router_ip:
print(f\’ – 默认网关: {router_ip}\’)
filter_str=\’udp and (port 67 or port 68)\’ # 设置过滤器仅捕获DHCP 流量
send_dhcp_discover() # 先发送DHCP DISCOVER消息
#sniff(prn=respond_to_dhcp_offer, filter=filter_str, store=0, iface=\’WLAN\’) # 然后开始监听并响应OFFER 消息
嗅探(prn=lambda x: Reply_to_dhcp_offer(x)或ack_ack(x),
过滤器=filter_str,存储=0,iface=\’WLAN\’)
客户端20代码:
从scapy.all 导入*
随机导入
导入时间
导入二进制密钥
从scapy.layers.dhcp 导入BOOTP、DHCP
从scapy.layers.inet 导入IP、UDP
从scapy.layers.l2 导入以太币
def send_dhcp_discover(接口=\’WLAN\’):
””
发送DHCP DISCOVER 消息
””
# 使用Binascii.hexlify 将MAC 地址字符串转换为原始字节
mac_bytes=binascii.unhexlify(\’00:11:22:33:44:66\’.replace(\’:\’, \’\’))
global client_t_mac #定义一个全局变量来存储client_mac地址
client_t_mac=mac_bytes
# print(f\’客户端mac 是:{clien_t_mac}\’)
dhcp_discover=以太(src=mac_bytes, dst=\’ff:ff:ff:ff:ff:ff\’) \\
/IP(src=\’0.0.0.0\’, dst=\’255.255.255.255\’) \\
/UDP(运动=68,d端口=67) \\
/BOOTP(chaddr=mac_bytes) \\
/DHCP(option=[(\’消息类型\’, \’检测\’), (\’终止\’)])
sendp(dhcp_discover, iface=接口, 详细=0)
print(\’客户端发送发现广播请求:src=\\\’0.0.0.0\\\’, dst=\\\’255.255.255.255\\\’\’)
def response_to_dhcp_offer(pkt):
””
响应收到的DHCP OFFER 消息
””
if DHCP in pkt and pkt[DHCP].options[0][1]==2: # 检查是否有DHCP OFFER 消息
server_id=pkt[DHCP].options[1][1] # 服务器ID
Offered_ip=pkt[BOOTP].yiaddr # 提供的IP地址
client_mac=pkt[Ether].src #客户端MAC地址
# print(f\’确保MAC地址与本机相同:{client_mac}\’)
print(f\’客户端收到报价响应消息:服务器ID:{server_id}报价ip:{offered_ip}\’)
# 使用正确的方式处理MAC地址
mac_bytes=binascii.unhexlify(\’00:11:22:33:44:66\’.replace(\’:\’, \’\’))
# 构建DHCP REQUEST 消息
dhcp_request=以太(src=mac_bytes, dst=\’ff:ff:ff:ff:ff:ff\’)/\\
IP(src=\’0.0.0.0\’, dst=\’255.255.255.255\’)/\\
UDP(运动=68,d端口=67)/\\
BOOTP(chaddr=mac_bytes, yiaddr=offered_ip)/\\
DHCP(选项=[
(\’消息类型\’, \’请求\’),
(\’requested_addr\’,offered_ip),
(\’服务器ID\’,服务器ID),
(\’结尾\’)
])
sendp(dhcp_request,verbose=0) #发送DHCP REQUEST消息
print(f\’广播(请求)发送请求的IP地址到服务器:{offered_ip} server ip: {server_id}\’)
默认ack_ack(pkt):
如果数据包中有DHCP 并且pkt[DHCP].options[0][1]==5:
client_ip=pkt[BOOTP].yiaddr # 分配给客户端的IP地址
subnet_mask=next((opt[1] for opt in pkt[DHCP].options if opt[0]==\’subnet_mask\’), None) # 子网掩码
router_ip=next((opt[1] for opt in pkt[DHCP].options if opt[0]==\’router\’), None) #默认网关
dns_servers=[opt[1] for opt in pkt[DHCP].options if opt[0]==6] # DNS 服务器列表
print(f\’客户端收到DHCP ACK 数据包:\’)
print(f\’ – 分配的IP 地址: {client_ip}\’)
对于子网掩码:
print(f\’ – 子网掩码: {subnet_mask}\’)
对于router_ip:
print(f\’ – 默认网关: {router_ip}\’)
filter_str=\’udp and (port 67 or port 68)\’ # 设置过滤器仅捕获DHCP 流量
send_dhcp_discover() # 先发送DHCP DISCOVER消息
#sniff(prn=respond_to_dhcp_offer, filter=filter_str, store=0, iface=\’WLAN\’) # 然后开始监听并响应OFFER 消息
嗅探(prn=lambda x: Reply_to_dhcp_offer(x)或ack_ack(x),
过滤器=filter_str,存储=0,iface=\’WLAN\’)
注:如果您是大学生,请记得返回时更改密码。
以上#使用Python编程模拟DHCP客户端和服务器的相关内容摘自网络,仅供参考。相关信息请参见官方公告。
原创文章,作者:CSDN,如若转载,请注明出处:https://www.sudun.com/ask/91624.html