title: Unable to send ICMP packets from a raw socket in Python
body: <p>I have a raw Python socket initialized like so:</p>
  
  <pre><code>mySocket = socket.socket(socket.AF_INET, socket.SOCK_RAW, socket.IPPROTO_RAW)
  mySocket.setsockopt(socket.IPPROTO_IP, socket.IP_HDRINCL, 1)
  </code></pre>
  
  <p>My problem is that I can't send any packet from the socket where the protocol field in my IP header is specified as '1' (ICMP). If this field is anything else it'll work just fine, including '17' (UDP) for example. I don't get any errors, the packet just doesn't display in Wireshark, and I can't receive it on my server.</p>
  
  <p>I'm generating the IP header like so:</p>
  
  <pre><code>def getIPHeader(src, dst, proto):
      version = 4
      IHL = 5
      DSCP = 0
      ECN = 0
      totalLength = 40
      identification = 333
      flags = 0
      fragmentOffset = 0
      timeToLive = 128
      protocol = proto
      headerChecksum = 0
      sourceIP = socket.inet_aton(src)
      destIP = socket.inet_aton(dst)
      options = 0
  
      version_IHL = (version &lt;&lt; 4) | IHL
      DSCP_ECN = (DSCP &lt;&lt; 2) | ECN
      flags_fragmentOffset = (flags &lt;&lt; 13) | fragmentOffset
  
      # The '!' ensures all arguments are converted to network byte order
      header = struct.pack("!BBHHHBBH4s4s", version_IHL, DSCP_ECN, totalLength, identification, flags_fragmentOffset, timeToLive, protocol, headerChecksum, sourceIP, destIP)
      return header
  </code></pre>
  
  <p>And sending like so:</p>
  
  <pre><code>icmpHeader = struct.pack("!bbHHh", 8, 0, 0, 666, 0)
  packet = getIPHeader("192.168.2.15", "8.8.8.8", 1) + icmpHeader
  mySocket.sendto(packet, ("8.8.8.8", 0))
  </code></pre>
  
  <p>Sending with UDP protocol set works (obviously malformed):</p>
  
  <pre><code>icmpHeader = struct.pack("!bbHHh", 8, 0, 0, 666, 0)
  packet = getIPHeader("192.168.2.15", "8.8.8.8", 17) + icmpHeader
  mySocket.sendto(packet, ("8.8.8.8", 0))
  </code></pre>
  
  <p>The worst part is if I send a ping from the command line, then copy the exact hex from Wireshark of the IP and ICMP data into my code, it STILL doesn't work, like so:</p>
  
  <pre><code>packet = b'\x45\x00\x00\x3c\x24\xad\x00\x00\x80\x01\x43\x4d\xc0\xa8\x02\x0f\x08\x08\x08\x08\x08\x00\x4d\x44\x00\x01\x00\x17\x61\x62\x63\x64\x65\x66\x67\x68\x69\x6a\x6b\x6c\x6d\x6e\x6f\x70\x71\x72\x73\x74\x75\x76\x77\x61\x62\x63\x64\x65\x66\x67\x68\x69'
  mySocket.sendto(packet, ("8.8.8.8", 0))
  </code></pre>
  
  <p>However, as before, if I change the 10th byte of the hard coded data to '\x11' (17 decimal, UDP), I can then see it in Wireshark (obviously with a malformed UDP section as the rest of the packet is ICMP).</p>
  
  <p>I'm running Windows 10, Python 3.4.1, and my firewall is off. Any ideas?</p>
  
  <p><strong>UPDATE:</strong> I've tried this on two different computers, a Windows 8 and a Windows 10 machine, both worked, so it's something to do with my computer, the plot thickens...</p>