Python Raw Socket to Ethernet Interface (Windows)

后端 未结 5 694
滥情空心
滥情空心 2021-01-15 06:14

I\'m trying to create a DHCP Server and the first step is for me to send packets through my ethernet port. I\'m trying to send packets to my Ethernet interface and having an

相关标签:
5条回答
  • 2021-01-15 06:24

    As said multiple times already, ETH_P_ALL is not implemented on Windows, due to Win32 limitations. The alternative is called Winpcap (more recently Npcap), which sets up Windows to access such low-level things (it adds an extra driver)

    What you can do then is to use a Winpcap/Npcap based library such as Scapy, to access Raw low-level sockets. This requires to install Npcap (or Winpcap) on the computer.

    Then you can either use the library as-is (it has lots of capabilities of handling packets), or if you want to have access to the raw data

    from scapy.all import *
    IFACES.show() # let’s see what interfaces are available. Windows only
    iface = <<"full iface name">> or <<IFACES.dev_from_index(12)>> or <<IFACES.dev_from_pcapname(r"\\Device_stuff")>>
    socket = conf.L2socket(iface=iface)
    # socket is now an Ethernet socket
    ### RECV
    packet_raw = socket.recv_raw()[0]  # Raw data
    packet_decoded = socket.recv() # Using the library (also contains things like sent time...)
    ### SEND
    socket.send(b"\x00......"). # send raw data
    socket.send(Ether()/IP(dst="www.google.com")/TCP()/Raw(load=b"data")) # use library
    
    0 讨论(0)
  • 2021-01-15 06:24

    Approaching your question from another direction: why do you need to work with ethernet at all? DHCP is usually implemented via UDP.

    1. DHCP server always has some IP address (and a pool of addresses it can lease).
    2. If a client wants and IP (DHCP actually can do much more than just assign IPs but let's stop on this use case for now), it sends a broadcast DHCPREQUEST with source IP 0.0.0.0 and destination IP 255.255.255.255. The servers answer him via UDP broadcast as well, but with his own source IP.

    If you want to create an implementation of DHCP, starting with OSI Level 2 (ethernet) will just give you headache of maintaining Level 3 (IP) and 4 (UDP). I don't see any benefit in this.

    If you'd like to create a DHCP-like protocol based on ethernet be ready to work on the following issue: routers don't forward broadcast packets unless asked to do so. For instance, for Cisco routers it looks like this:

    router(config)# interface ethernet 0/0
    router(config-if)# ip helper-address 10.1.23.5
    router(config-if)# end
    router#
    

    Thus we configure router so it knows there's something helpful connected to ethernet 0/0 port with IP 10.1.23.5 that needs broadcasts (source).

    0 讨论(0)
  • 2021-01-15 06:29

    Looks like you don't get access to ethernet with this socket:

    s = socket.socket(socket.AF_INET, socket.SOCK_RAW, socket.IPPROTO_RAW)
    

    socket.IPPROTO_RAW gives you access to Level 3 protocol (IP), whereas ethernet is on Level 1 and 2. At level 3 an ethernet frame is already analyzed and its headers discarded. You need to get to Level 2 and ETH_P_ALL protocol seems to be a nice place to start. I don't believe python socket module implements it on that low level, but you can interact with WinAPI via ctypes module.

    0 讨论(0)
  • 2021-01-15 06:35

    This example from the docs seems instructive. https://docs.python.org/2/library/socket.html

    import socket
    
    # the public network interface
    HOST = socket.gethostbyname(socket.gethostname())
    
    # create a raw socket and bind it to the public interface
    s = socket.socket(socket.AF_INET, socket.SOCK_RAW, socket.IPPROTO_IP)
    s.bind((HOST, 0))
    
    # Include IP headers
    s.setsockopt(socket.IPPROTO_IP, socket.IP_HDRINCL, 1)
    
    # receive all packages
    s.ioctl(socket.SIO_RCVALL, socket.RCVALL_ON)
    
    # receive a package
    print s.recvfrom(65565)
    
    # disabled promiscuous mode
    s.ioctl(socket.SIO_RCVALL, socket.RCVALL_OFF)
    

    I think the key is socket.gethostbyname(socket.gethostname()). "eth0" as used in your example won't be supported on Windows.

    0 讨论(0)
  • 2021-01-15 06:43

    DHCP is a UDP protocol. You shouldn't need a raw socket to implement a DHCP server.

    Use an AF_INET/SOCK_DGRAM socket, and bind to address 255.255.255.255 in order to implement your server.

    0 讨论(0)
提交回复
热议问题