Python Raw Socket to Ethernet Interface (Windows)
<p>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 error popping up.</p>

<p>The code is below.</p>

<pre><code>import socket

def sendeth(src, dst, eth_type, payload, interface = "eth0"):
  """Send raw Ethernet packet on interface."""

  assert(len(src) == len(dst) == 6) # 48-bit ethernet addresses
  assert(len(eth_type) == 2) # 16-bit ethernet type

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

  # From the docs: "For raw packet
  # sockets the address is a tuple (ifname, proto [,pkttype [,hatype]])"
  s.bind((interface, 0))
  return s.send(src + dst + eth_type + payload)

if __name__ == "__main__":
  print("Sent %d-byte Ethernet packet on eth0" %
    sendeth("\xFE\xED\xFA\xCE\xBE\xEF",
            "\xFE\xED\xFA\xCE\xBE\xEF",
            "\x7A\x05",
            "hello"))
</code></pre>

<p>I was having issues with the way the socket was being created. AF_PACKET is not recognized so I'm assuming that only works for Linux. I commented it out and added a new line below it. I ran it again and I started getting an error shown below.</p>

<pre><code>Traceback (most recent call last):
  File "eth.py", line 27, in &lt;module&gt;
    "hello"))
  File "eth.py", line 19, in sendeth
    s.bind((interface, 0))
  File "C:\Python27\lib\socket.py", line 224, in meth
    return getattr(self._sock,name)(*args)
socket.gaierror: [Errno 11001] getaddrinfo failed
</code></pre>

<p>Does anyone know why this is happening?</p>

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

<ol>
<li>DHCP server always has some IP address (and a pool of addresses it can lease).</li>
<li>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.</li>
</ol>

<p>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.</p>

<p>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:</p>

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

<p>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 (<a href="https://supportforums.cisco.com/document/13916/router-not-forwarding-dhcp-requests-hosts-are-unable-obtain-ip-address-dhcp-server" rel="nofollow">source</a>). </p>

python windows python-2.7 sockets dhcp