DHCP的工作原理与流程

DHCP工作原理

目前让设备使用IP地址的方法主要有两种:静态设置IP动态分配IP地址。一些组织往往会使用静态设置IP地址的方法这就需要用户在网络中设定IP地址,,网关和DNS等信息。而更多情况下,人们使用的都是动态分配IP地址的方法。

DHCP的工作原理与流程

(1) DHCP客户端在局域网内发送一个DHCP Discover数据包,目的是发现能够给它提供IP地址的DHCP服务器端。

(2) 接收到DHCP Discover数据包的DHCP服务器端会向请求的DHCP客户端发送一个DHCP Offer数据包,其中包含了可以使用的IP地址。

(3) 如果DHCP 客户端接收到多个DHCP Offer数据包,那么只会处理最先收到的。然后DHCP客户端会广播一个DHCP Request数据包,声明自己选用的DHCP服务器端和IP地址。

(4) DHCP 服务器端在接收到DHCP客户端广播的DHCP Request数据包后,就会判断该数据包中的IP地址是否与自己的地址相同。如果相同,就会像DHCP客户端发送一个响应的DHCP ACK数据包。

使用Python程序模拟DHCP客户端

DHCP数据包与Scapy函数对应关系如图所示:

DHCP动态分配IP地址时,DHCP客户端与DHCP服务器端一共发送了4个数据包,我们的工作就是使用scapy来构造这些数据包。困难在于每个数据包都需要设置其中的Ether,IP,UDP,BOOTP,DHCP这5个协议的内容。

DHCP Discover 数据包的构造

DHCP采用UDP作为传输层协议,DHCP客户端发送请求消息到DHCP服务端的67号端口,DHCP服务器端回应应答消息给DHCP客户端的68号端口。DHCP客户端以广播的方式发送DHCP Discover数据包,现在我们就来构造一个DHCP Discover数据包,实现代码如下

import random

from scapy.all import *
from scapy.layers.inet import IP,Ether,UDP,ICMP
from scapy.layers.dhcp import DHCP,BOOTP
import binascii
from scapy.volatile import RandMAC


mac_random = str(RandMAC())
Ether_Discover = Ether(src=mac_random,dst="ff:ff:ff:ff:ff:ff")
IP_Discover = IP(src="0.0.0.0",dst="255.255.255.255")
UDP_Discover = UDP(sport=68,dport=67)
client_mac_id = binascii.unhexlify(mac_random.replace(':',''))
xid_random = random.randint(1,900000000)

BOOTP_Discover = BOOTP(chaddr=client_mac_id,xid=xid_random)
DHCP_Discover = DHCP(options=[("message-type","discover"),"end"])
Discover = Ether_Discover/IP_Discover/UDP_Discover/BOOTP_Discover/DHCP_Discover
sendp(Discover,iface="以太网 2")
print("

Sending DHCPDISCOVER on"+"以太网")

DHCP Offer 数据包的捕获与解析

由于整个DHCP通信过程需要4个数据包,因此DHCP客户端需要捕获并解析DHCP服务器端发送的DHCP Offer数据包,才能继续进行后面的过程,这里我们可以使用Wireshark等抓包工具捕获DHCP数据包。

DHCP Request 数据包的构造

from scapy.layers.dhcp import BOOTP,DHCP
from scapy.layers.inet import Ether,IP,ICMP,UDP
from scapy.all import *
import binascii

def detect_dhcp(pkt):
    if DHCP in pkt:
        if pkt[DHCP].options[0][1] ==2:
            Ether_Request =Ether(src=pkt[Ether].dst,dst="ff:ff:ff:ff:ff:ff")
            IP_Request=IP(src="0.0.0.0",dst="255.255.255.255")
            UDP_Request=UDP(sport=68,dport=67)
            BOOTP_Request=BOOTP(chaddr=pkt[BOOTP].chaddr,xid=pkt[BOOTP].xid)
            DHCP_Request=DHCP(options=[("message-type",'request'),("server_id",pkt[DHCP].options[1][1]),("requested_addr",pkt[BOOTP].yiaddr),"end"])
            Request=Ether_Request/IP_Request/UDP_Request/BOOTP_Request/DHCP_Request
            sendp(Request,iface='以太网')
            print(pkt[BOOTP].yiaddr+"正在分配")
            if pkt[DHCP].options[0][1]==5:
                print(pkt[BOOTP].yiaddr+"已经分配")
            sniff(filter="src port 67",iface='以太网',prn=detect_dhcp,count=10)
``





© 版权声明
THE END
如果内容对您有所帮助,就支持一下吧!
点赞0 分享
评论 抢沙发

请登录后发表评论

    暂无评论内容