用python编程实现对DHCP客户端和服务器的模拟,python写tcp服务器

用python编程实现对DHCP客户端和服务器的模拟用python编写两个代码,用于模拟DHCP协议的动态分配IP的过程,因为之前遇到一个课程实现,不下心选择了DHCP这个题目,网上能

使用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

(0)
CSDN's avatarCSDN
上一篇 2024年6月22日 下午8:31
下一篇 2024年6月22日 下午9:07

相关推荐

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注