dhcp 服务器包括 dhcp discover,offer,request,ack problem

问题描述 投票:0回答:2

这是我的 dhcp 服务器:

import socket
from scapy.all import *
from scapy.layers.dhcp import BOOTP, DHCP
from scapy.layers.inet import UDP, IP
from scapy.layers.l2 import Ether


def dhcp_server():
    # Server parameters
    server_ips = ['127.0.0.1']
    server_port = 67

    # Create a UDP socket for DHCP communication
    dhcp_socket = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
    dhcp_socket.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
    dhcp_socket.bind(('127.0.0.1', server_port))
    print(f"DHCP server listening on port {server_port}")

    # Loop to handle incoming DHCP requests
    while True:
        # Receive a DHCP request from a client
        dhcp_request, client_address = dhcp_socket.recvfrom(1024)
        print(f"Received DHCP request from {client_address[0]}:{client_address[1]}")

        # Parse the DHCP request packet
        dhcp_packet = DHCP(dhcp_request)
        dhcp_options = dhcp_packet[DHCP].options
        if not dhcp_options:
            print(f"Invalid DHCP request from {client_address[0]}:{client_address[1]}")
            continue
        dhcp_message_type = [opt[1] for opt in dhcp_options if opt[0] == 'message-type'][0]
        client_mac_address = dhcp_packet[Ether].src

        # Assign an IP address to the client
        if dhcp_message_type == 1:  # DHCP Discover
            # Create a DHCP offer packet
            dhcp_offer = Ether(src=get_if_hwaddr('eth0'), dst=client_mac_address) / IP(src=server_ips[0],
                                                                                       dst='255.255.255.255') / UDP(
                sport=67, dport=68) / BOOTP(op=2, yiaddr='0.0.0.0', siaddr=server_ips[0],
                                            chaddr=client_mac_address) / DHCP(
                options=[('message-type', 'offer'), ('subnet_mask', '255.255.255.0'), ('domain_name_server', '8.8.8.8'),
                         ('router', server_ips[0]), ('lease_time', 120)])

            # Send the DHCP offer packet to the client
            sendp(dhcp_offer, iface='eth0', verbose=0)
            print(f"Sent DHCP offer to {client_address[0]}:{client_address[1]}")

        elif dhcp_message_type == 3:  # DHCP Request
            # Create a DHCP acknowledgement packet
            dhcp_ack = Ether(src=get_if_hwaddr('eth0'), dst=client_mac_address) / IP(src=server_ips[0],
                                                                                     dst='255.255.255.255') / UDP(
                sport=67, dport=68) / BOOTP(op=2, yiaddr=dhcp_packet[BOOTP].yiaddr, siaddr=server_ips[0],
                                            chaddr=client_mac_address) / DHCP(
                options=[('message-type', 'ack'), ('subnet_mask', '255.255.255.0'), ('domain_name_server', '8.8.8.8'),
                         ('router', server_ips[0]), ('lease_time', 120)])

            # Send the DHCP acknowledgement packet to the client
            sendp(dhcp_ack, iface='eth0', verbose=0)
            print(f"Sent DHCP acknowledgement to {client_address[0]}:{client_address[1]}")


if __name__ == "__main__":
    dhcp_server()

我的 dhcp 服务器监听传入的请求并相应地响应它们。

这是我的客户:

import socket
import struct

# Client parameters
server_ip = '127.0.0.1'
server_port = 67

# Create a UDP socket for DHCP communication
dhcp_socket = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
dhcp_socket.bind(('0.0.0.0', 68))  # Use port 68 for DHCP client

# Construct the DHCP request message
# See https://datatracker.ietf.org/doc/html/rfc2131#section-2
# for the format of a DHCP request message
transaction_id = b'\x39\x03\xF3\x26'  # 4-byte transaction ID
flags = b'\x00\x01'  # Broadcast flag (bit 15) set to 1
client_hw_address = b'\x08\x00\x27\x01\x9C\xEA'  # Example MAC address
client_ip_address = b'\x00\x00\x00\x00'  # Requesting a new IP address
server_ip_address = b'\x00\x00\x00\x00'  # Server IP address is initially 0
relay_agent_ip_address = b'\x00\x00\x00\x00'  # No relay agent in this case
client_mac_padding = b'\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00'
dhcp_options = b'\x63\x82\x53\x63'  # Magic cookie + DHCP options
dhcp_options += b'\x35\x01\x01'  # DHCP Message Type option: DHCPREQUEST
dhcp_options += b'\x32\x04\xc0\xa8\x01\x64'  # Requested IP address option
dhcp_options += b'\x0f\x06\x00\x00\x3c\x50\x4b\x05\xdc'  # Hostname option
dhcp_options += b'\x0c\x0c\x70\x79\x74\x68\x6f\x6e\x2d\x62\x6f\x6f\x74'  # Hostname option
dhcp_options += b'\x37\x04\x01\x03\x06\x2c'  # Parameter Request List option
dhcp_request = b'\x01'  # Message Type: DHCPDISCOVER
dhcp_request += client_mac_padding + client_hw_address
dhcp_request += client_mac_padding + client_ip_address
dhcp_request += server_ip_address + relay_agent_ip_address
dhcp_request += transaction_id + client_mac_padding
dhcp_request += dhcp_options + b'\xff'  # End of DHCP options

# Send the DHCP request to the DHCP server
dhcp_socket.sendto(dhcp_request, (server_ip, server_port))
print(f"Sent DHCP request to {server_ip}:{server_port}")

# Wait for the DHCP response from the server
dhcp_response, server_address = dhcp_socket.recvfrom(1024)
print(f"Received DHCP response '{dhcp_response.hex()}' from {server_address[0]}:{server_address[1]}")
if len(dhcp_response) < 240:
    print('Error: Malformed DHCP response')
else:
    dhcp_header = struct.unpack('!B B B B 4s 2s 2s 4s 4s 4s 4s 6s', dhcp_response[:28])
    dhcp_options = dhcp_response[240:]
    dhcp_message_type = dhcp_options[2]
    if dhcp_message_type == 0x02:  # DHCP offer
        offered_ip_address = socket.inet_ntoa(dhcp_options[16:20])
        print(f"DHCP server offered IP address {offered_ip_address}")
        dhcp_xid = dhcp_header[3]
        # Construct the DHCP request packet
        dhcp_request = struct.pack('!B B B B 4s 2s 2s 4s 4s 4s 4s 6s', 0x01, 0x01, 0x06, 0x00,
                                   dhcp_header[4], dhcp_header[5], dhcp_header[6], b'\x00\x00\x00\x00',
                                   dhcp_header[8], b'\x00\x00\x00\x00', dhcp_header[10], dhcp_header[11])
        dhcp_request += struct.pack('!B B B B', 0x35, 0x01, 0x03, 0x0f)  # DHCP message type: Request
        dhcp_request += struct.pack('!B B B B', 0x32, 0x04, 0x00, 0x00, 0x1c)  # DHCP requested IP address
        dhcp_request += struct.pack('!B B B B', 0x37, 0x03, 0x03, 0x01, 0x06)  # DHCP parameter request list
        dhcp_request += struct.pack('!B B B B', 0xff, 0x00, 0x00, 0x00)  # End of options
        # Send the DHCP request packet to the server
        dhcp_socket.sendto(dhcp_request, (server_ip, server_port))
        print(f"Sent DHCP request for IP address {offered_ip_address}")
        # Wait for the DHCP response to the request
        dhcp_response, server_address = dhcp_socket.recvfrom(1024)
        print(f"Received DHCP response '{dhcp_response.hex()}' from {server_address[0]}:{server_address[1]}")
        if len(dhcp_response) < 240:
            print('Error: Malformed DHCP response')
        else:
            dhcp_header = struct.unpack('!B B B B 4s 2s 2s 4s 4s 4s 4s 6s', dhcp_response[:28])
            dhcp_options = dhcp_response[240:]
            dhcp_message_type = dhcp_options[2]
            if dhcp_message_type == 0x05:  # DHCP ack
                assigned_ip_address = socket.inet_ntoa(dhcp_options[16:20])
                print(f"DHCP server assigned IP address {assigned_ip_address}")

我的客户端向 google.com 发送一个 ping 并使用本地主机 ip 等待服务器的响应并且它不工作,我收到一条 dhcp discover 发送的消息,仅此而已,没有响应。

现在有一个问题,服务器正在监听传入的请求,但是当我激活我的客户端时,它没有响应数据包,我可以在我的代码中修复任何问题以使其正常工作,我已经尝试了几个客户端和改进它的方法,但它不起作用,

python networking network-programming dhcp
2个回答
0
投票

问题解决了,不用再回答了


0
投票

作为@krishh 的请求,分享它是如何解决问题的:所以我的想法是我需要在发送响应之前提取数据包的全部信息,所以当我得到一个 DHCP Discoer 时,我需要返回一个 DHCP offer 是向客户端提供和 ip,然后如果他想要这个 ip,那么他依次发送请求并由服务器获取和确认,所以这是如何完成握手和发送响应的,我共享的代码有进行修改,以便它可以正确地拥有所有数据包标头以及客户端,以便它可以正确地请求。

© www.soinside.com 2019 - 2024. All rights reserved.