DHCP服务器包括DHCP Discover、Offer、Request、Ack问题。

huangapple go评论122阅读模式
英文:

dhcp server including dhcp discover,offer,request,ack problem

问题

以下是翻译好的部分:

在DHCP服务器方面,您的代码主要是一个DHCP服务器实现,它监听来自客户端的DHCP请求并作出相应的回应。

在客户端方面,您的代码主要是一个DHCP客户端实现,它创建一个DHCP请求消息,然后将其发送到DHCP服务器,等待服务器的响应。

您提到您的客户端发送ping到google.com并等待服务器响应,但没有收到回应。在您的描述中没有提供足够的信息来确定问题的根本原因,但可以有许多潜在原因导致这个问题。可能需要进一步的调试和排查,以确定问题的确切原因。

如果您希望更详细的帮助或有特定的问题,请提供更多信息,我将尽力协助。

英文:

this is my dhcp server:

  1. import socket
  2. from scapy.all import *
  3. from scapy.layers.dhcp import BOOTP, DHCP
  4. from scapy.layers.inet import UDP, IP
  5. from scapy.layers.l2 import Ether
  6. def dhcp_server():
  7. # Server parameters
  8. server_ips = ['127.0.0.1']
  9. server_port = 67
  10. # Create a UDP socket for DHCP communication
  11. dhcp_socket = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
  12. dhcp_socket.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
  13. dhcp_socket.bind(('127.0.0.1', server_port))
  14. print(f"DHCP server listening on port {server_port}")
  15. # Loop to handle incoming DHCP requests
  16. while True:
  17. # Receive a DHCP request from a client
  18. dhcp_request, client_address = dhcp_socket.recvfrom(1024)
  19. print(f"Received DHCP request from {client_address[0]}:{client_address[1]}")
  20. # Parse the DHCP request packet
  21. dhcp_packet = DHCP(dhcp_request)
  22. dhcp_options = dhcp_packet[DHCP].options
  23. if not dhcp_options:
  24. print(f"Invalid DHCP request from {client_address[0]}:{client_address[1]}")
  25. continue
  26. dhcp_message_type = [opt[1] for opt in dhcp_options if opt[0] == 'message-type'][0]
  27. client_mac_address = dhcp_packet[Ether].src
  28. # Assign an IP address to the client
  29. if dhcp_message_type == 1: # DHCP Discover
  30. # Create a DHCP offer packet
  31. dhcp_offer = Ether(src=get_if_hwaddr('eth0'), dst=client_mac_address) / IP(src=server_ips[0],
  32. dst='255.255.255.255') / UDP(
  33. sport=67, dport=68) / BOOTP(op=2, yiaddr='0.0.0.0', siaddr=server_ips[0],
  34. chaddr=client_mac_address) / DHCP(
  35. options=[('message-type', 'offer'), ('subnet_mask', '255.255.255.0'), ('domain_name_server', '8.8.8.8'),
  36. ('router', server_ips[0]), ('lease_time', 120)])
  37. # Send the DHCP offer packet to the client
  38. sendp(dhcp_offer, iface='eth0', verbose=0)
  39. print(f"Sent DHCP offer to {client_address[0]}:{client_address[1]}")
  40. elif dhcp_message_type == 3: # DHCP Request
  41. # Create a DHCP acknowledgement packet
  42. dhcp_ack = Ether(src=get_if_hwaddr('eth0'), dst=client_mac_address) / IP(src=server_ips[0],
  43. dst='255.255.255.255') / UDP(
  44. sport=67, dport=68) / BOOTP(op=2, yiaddr=dhcp_packet[BOOTP].yiaddr, siaddr=server_ips[0],
  45. chaddr=client_mac_address) / DHCP(
  46. options=[('message-type', 'ack'), ('subnet_mask', '255.255.255.0'), ('domain_name_server', '8.8.8.8'),
  47. ('router', server_ips[0]), ('lease_time', 120)])
  48. # Send the DHCP acknowledgement packet to the client
  49. sendp(dhcp_ack, iface='eth0', verbose=0)
  50. print(f"Sent DHCP acknowledgement to {client_address[0]}:{client_address[1]}")
  51. if __name__ == "__main__":
  52. dhcp_server()

my dhcp server listens to incomming requests and respond to them accordingly.

this is my client:

  1. import socket
  2. import struct
  3. # Client parameters
  4. server_ip = '127.0.0.1'
  5. server_port = 67
  6. # Create a UDP socket for DHCP communication
  7. dhcp_socket = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
  8. dhcp_socket.bind(('0.0.0.0', 68)) # Use port 68 for DHCP client
  9. # Construct the DHCP request message
  10. # See https://datatracker.ietf.org/doc/html/rfc2131#section-2
  11. # for the format of a DHCP request message
  12. transaction_id = b'\x39\x03\xF3\x26' # 4-byte transaction ID
  13. flags = b'\x00\x01' # Broadcast flag (bit 15) set to 1
  14. client_hw_address = b'\x08\x00\x27\x01\x9C\xEA' # Example MAC address
  15. client_ip_address = b'\x00\x00\x00\x00' # Requesting a new IP address
  16. server_ip_address = b'\x00\x00\x00\x00' # Server IP address is initially 0
  17. relay_agent_ip_address = b'\x00\x00\x00\x00' # No relay agent in this case
  18. client_mac_padding = b'\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00'
  19. dhcp_options = b'\x63\x82\x53\x63' # Magic cookie + DHCP options
  20. dhcp_options += b'\x35\x01\x01' # DHCP Message Type option: DHCPREQUEST
  21. dhcp_options += b'\x32\x04\xc0\xa8\x01\x64' # Requested IP address option
  22. dhcp_options += b'\x0f\x06\x00\x00\x3c\x50\x4b\x05\xdc' # Hostname option
  23. dhcp_options += b'\x0c\x0c\x70\x79\x74\x68\x6f\x6e\x2d\x62\x6f\x6f\x74' # Hostname option
  24. dhcp_options += b'\x37\x04\x01\x03\x06\x2c' # Parameter Request List option
  25. dhcp_request = b'\x01' # Message Type: DHCPDISCOVER
  26. dhcp_request += client_mac_padding + client_hw_address
  27. dhcp_request += client_mac_padding + client_ip_address
  28. dhcp_request += server_ip_address + relay_agent_ip_address
  29. dhcp_request += transaction_id + client_mac_padding
  30. dhcp_request += dhcp_options + b'\xff' # End of DHCP options
  31. # Send the DHCP request to the DHCP server
  32. dhcp_socket.sendto(dhcp_request, (server_ip, server_port))
  33. print(f"Sent DHCP request to {server_ip}:{server_port}")
  34. # Wait for the DHCP response from the server
  35. dhcp_response, server_address = dhcp_socket.recvfrom(1024)
  36. print(f"Received DHCP response '{dhcp_response.hex()}' from {server_address[0]}:{server_address[1]}")
  37. if len(dhcp_response) < 240:
  38. print('Error: Malformed DHCP response')
  39. else:
  40. dhcp_header = struct.unpack('!B B B B 4s 2s 2s 4s 4s 4s 4s 6s', dhcp_response[:28])
  41. dhcp_options = dhcp_response[240:]
  42. dhcp_message_type = dhcp_options[2]
  43. if dhcp_message_type == 0x02: # DHCP offer
  44. offered_ip_address = socket.inet_ntoa(dhcp_options[16:20])
  45. print(f"DHCP server offered IP address {offered_ip_address}")
  46. dhcp_xid = dhcp_header[3]
  47. # Construct the DHCP request packet
  48. dhcp_request = struct.pack('!B B B B 4s 2s 2s 4s 4s 4s 4s 6s', 0x01, 0x01, 0x06, 0x00,
  49. dhcp_header[4], dhcp_header[5], dhcp_header[6], b'\x00\x00\x00\x00',
  50. dhcp_header[8], b'\x00\x00\x00\x00', dhcp_header[10], dhcp_header[11])
  51. dhcp_request += struct.pack('!B B B B', 0x35, 0x01, 0x03, 0x0f) # DHCP message type: Request
  52. dhcp_request += struct.pack('!B B B B', 0x32, 0x04, 0x00, 0x00, 0x1c) # DHCP requested IP address
  53. dhcp_request += struct.pack('!B B B B', 0x37, 0x03, 0x03, 0x01, 0x06) # DHCP parameter request list
  54. dhcp_request += struct.pack('!B B B B', 0xff, 0x00, 0x00, 0x00) # End of options
  55. # Send the DHCP request packet to the server
  56. dhcp_socket.sendto(dhcp_request, (server_ip, server_port))
  57. print(f"Sent DHCP request for IP address {offered_ip_address}")
  58. # Wait for the DHCP response to the request
  59. dhcp_response, server_address = dhcp_socket.recvfrom(1024)
  60. print(f"Received DHCP response '{dhcp_response.hex()}' from {server_address[0]}:{server_address[1]}")
  61. if len(dhcp_response) < 240:
  62. print('Error: Malformed DHCP response')
  63. else:
  64. dhcp_header = struct.unpack('!B B B B 4s 2s 2s 4s 4s 4s 4s 6s', dhcp_response[:28])
  65. dhcp_options = dhcp_response[240:]
  66. dhcp_message_type = dhcp_options[2]
  67. if dhcp_message_type == 0x05: # DHCP ack
  68. assigned_ip_address = socket.inet_ntoa(dhcp_options[16:20])
  69. print(f"DHCP server assigned IP address {assigned_ip_address}")

my client send a ping to google.com and wait for a respond from the server using the localhost ip and it is not working, i get a message that the dhcp discover sent and that's it, no respond.

now there is a problem that the server is listening to the incomming request but when i activate my client it does not resond to the packet, is there anything i could fix in my code for it to work properly, i have tried several client and ways to improve it but yet it is not working,

答案1

得分: 0

问题已解决,不需要再回答。

英文:

the problem is solved, no need to answer anymore.

答案2

得分: 0

根据 @krishh 的要求分享解决问题的过程:所以这个想法是,在发送响应之前,我需要提取包的所有信息,所以当我收到 DHCP Discover 时,我需要返回一个 DHCP Offer,这是为客户端提供一个 IP 地址,然后如果客户端想要这个 IP 地址,他会发送一个请求,然后服务器会响应一个确认,这就是握手的过程,然后响应被发送。我分享的代码需要进行修改,以便正确包含所有包头以及客户端,以便可以正确请求。

英文:

as a request of @krishh to share how it went about solving the problem: so the idea was that i need to extract the whole info of the packet before send a response, so when i get an DHCP Discoer i need to return a DHCP offer which is to offer and ip to the client then if he wants this ip then he in his turn sends a request and gets and ack by the server so this how is the handshake is done and the respond is sent, the code i shared had to be modified so it can have all of the packet headers properly as well as the client so it can request properly.

huangapple
  • 本文由 发表于 2023年3月15日 18:14:46
  • 转载请务必保留本文链接:https://go.coder-hub.com/75743302.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定