title: RAW ICMP socket: recvfrom() not recieving any data
body: <p>The following code is a program designed to send ICMP echo requests and receive replies.</p>
  
  <pre><code>/*
      Forgive my lack of error handling :)
  */
  SOCKET ASOCKET = INVALID_SOCKET;
  struct sockaddr saddr;
  struct sockaddr_in *to = (struct sockaddr_in *) &amp;saddr;
  struct sockaddr_in from;
  int fromsize = sizeof(from);
  std::string ip = "[arbitrary ip address]";
  
  struct ICMP {
      USHORT type;
      USHORT code;
      USHORT cksum;
      USHORT id;
      USHORT seq;
  }*_ICMP;
  
  char sendBuffer[sizeof(struct ICMP)];
  char recvBuffer[256];
  
  WSADATA wsaData;
  WSAStartup(MAKEWORD(2, 2), &amp;wsaData);
  
  memset(&amp;saddr, NULL, sizeof(saddr));
  ASOCKET = socket(AF_INET, SOCK_RAW, IPPROTO_ICMP);
  
  //  Configure timeout
  DWORD timeoutmilsec = 3000;
  setsockopt(ASOCKET, SOL_SOCKET, SO_RCVTIMEO, (char *)&amp;timeoutmilsec, sizeof(timeoutmilsec));
  
  to-&gt;sin_family = AF_INET;
  inet_pton(AF_INET, ip.c_str(), &amp;(to-&gt;sin_addr));
  
  _ICMP = new ICMP();
  
  _ICMP-&gt;type = 8;
  _ICMP-&gt;code = 0;
  _ICMP-&gt;cksum = 0;
  _ICMP-&gt;id = rand();
  _ICMP-&gt;seq++;
  // I have omitted my declaration of checksum() for simplicity
  _ICMP-&gt;cksum = checksum((u_short *)_ICMP, sizeof(struct ICMP));
  
  memcpy(sendBuffer, _ICMP, sizeof(struct ICMP));
  
  if (sendto(ASOCKET, sendBuffer, sizeof(sendBuffer), NULL, (sockaddr *)&amp;saddr, sizeof(saddr)) == SOCKET_ERROR)
  {
      printf("sendto() failed with error: %u\n", WSAGetLastError());
      return false;
  }
  
  if (recvfrom(ASOCKET, recvBuffer, sizeof(recvBuffer), NULL, (sockaddr *)&amp;from, &amp;fromsize) == SOCKET_ERROR)
  {
      if (WSAGetLastError() == TIMEOUTERROR)
      {
          printf("Timed out\n\n");
          return false;
      }
  
      printf("recvfrom() failed with error: %u\n", WSAGetLastError());
      return false;
  }
  </code></pre>
  
  <p>My issue is that my <code>recvfrom()</code> call does not receive any data and returns TIMEOUTERROR (10060) despite the fact that the ping <strong>has</strong> been replied to (Wireshark captures the request and reply being sent). <code>sendto()</code> works but <code>recvfrom()</code> behaves weirdly and I can't figure out what the problem is.</p>
  
  <p>What I find interesting is <code>recvfrom()</code> will receive data only when the gateway tells me that a host is unreachable; it won't if the host is reachable and has responded to the ping.</p>