ReactOS  0.4.14-dev-593-g1793dcc
icmp.c File Reference
#include "config.h"
#include "wine/port.h"
#include <sys/types.h>
#include <stdarg.h>
#include <string.h>
#include <stdio.h>
#include <errno.h>
#include <fcntl.h>
#include "windef.h"
#include "winbase.h"
#include "winerror.h"
#include "winternl.h"
#include "ipexport.h"
#include "icmpapi.h"
#include "wine/debug.h"
#include "ip.h"
#include "ip_icmp.h"
Include dependency graph for icmp.c:

Go to the source code of this file.

Classes

struct  icmp_t
 

Macros

#define USE_WS_PREFIX
 
#define BIG_ENDIAN   4321
 
#define LITTLE_ENDIAN   1234
 
#define BYTE_ORDER   LITTLE_ENDIAN
 
#define u_int16_t   WORD
 
#define u_int32_t   DWORD
 
#define IP_OPTS_UNKNOWN   0
 
#define IP_OPTS_DEFAULT   1
 
#define IP_OPTS_CUSTOM   2
 

Functions

 WINE_DEFAULT_DEBUG_CHANNEL (icmp)
 
 WINE_DECLARE_DEBUG_CHANNEL (winediag)
 
static int in_cksum (u_short *addr, int len)
 
HANDLE WINAPI Icmp6CreateFile (VOID)
 
DWORD WINAPI Icmp6SendEcho2 (HANDLE IcmpHandle, HANDLE Event, PIO_APC_ROUTINE ApcRoutine, PVOID ApcContext, struct sockaddr_in6 *SourceAddress, struct sockaddr_in6 *DestinationAddress, LPVOID RequestData, WORD RequestSize, PIP_OPTION_INFORMATION RequestOptions, LPVOID ReplyBuffer, DWORD ReplySize, DWORD Timeout)
 
HANDLE WINAPI IcmpCreateFile (VOID)
 
BOOL WINAPI IcmpCloseHandle (HANDLE IcmpHandle)
 
static DWORD system_icmp (IPAddr DestinationAddress, LPVOID RequestData, WORD RequestSize, PIP_OPTION_INFORMATION RequestOptions, LPVOID ReplyBuffer, DWORD ReplySize, DWORD Timeout)
 
DWORD WINAPI IcmpSendEcho (HANDLE IcmpHandle, IPAddr DestinationAddress, LPVOID RequestData, WORD RequestSize, PIP_OPTION_INFORMATION RequestOptions, LPVOID ReplyBuffer, DWORD ReplySize, DWORD Timeout)
 
DWORD WINAPI IcmpSendEcho2 (HANDLE IcmpHandle, HANDLE Event, PIO_APC_ROUTINE ApcRoutine, PVOID ApcContext, IPAddr DestinationAddress, LPVOID RequestData, WORD RequestSize, PIP_OPTION_INFORMATION RequestOptions, LPVOID ReplyBuffer, DWORD ReplySize, DWORD Timeout)
 
DWORD WINAPI IcmpSendEcho2Ex (HANDLE IcmpHandle, HANDLE Event, PIO_APC_ROUTINE ApcRoutine, PVOID ApcContext, IPAddr SourceAddress, IPAddr DestinationAddress, LPVOID RequestData, WORD RequestSize, PIP_OPTION_INFORMATION RequestOptions, LPVOID ReplyBuffer, DWORD ReplySize, DWORD Timeout)
 

Variables

static LONG icmp_sequence =0
 

Macro Definition Documentation

◆ BIG_ENDIAN

#define BIG_ENDIAN   4321

Definition at line 89 of file icmp.c.

◆ BYTE_ORDER

#define BYTE_ORDER   LITTLE_ENDIAN

Definition at line 98 of file icmp.c.

◆ IP_OPTS_CUSTOM

#define IP_OPTS_CUSTOM   2

Definition at line 125 of file icmp.c.

◆ IP_OPTS_DEFAULT

#define IP_OPTS_DEFAULT   1

Definition at line 124 of file icmp.c.

◆ IP_OPTS_UNKNOWN

#define IP_OPTS_UNKNOWN   0

Definition at line 123 of file icmp.c.

◆ LITTLE_ENDIAN

#define LITTLE_ENDIAN   1234

Definition at line 92 of file icmp.c.

◆ u_int16_t

Definition at line 102 of file icmp.c.

◆ u_int32_t

Definition at line 103 of file icmp.c.

◆ USE_WS_PREFIX

#define USE_WS_PREFIX

Definition at line 76 of file icmp.c.

Function Documentation

◆ Icmp6CreateFile()

HANDLE WINAPI Icmp6CreateFile ( VOID  )

Definition at line 164 of file icmp.c.

165 {
166  icmp_t* icp;
167 #ifdef __REACTOS__
168  int sid;
169  WSADATA wsaData;
170 
171  if (WSAStartup(MAKEWORD(2, 2), &wsaData) != ERROR_SUCCESS)
172  {
173  ERR_(winediag)("Failed to use ICMPV6 (network ping), this requires special permissions.\n");
174  return INVALID_HANDLE_VALUE;
175  }
176 
177  sid=socket(AF_INET6,SOCK_RAW,IPPROTO_ICMPV6);
178 #else
179 
180  int sid=socket(AF_INET6,SOCK_RAW,IPPROTO_ICMPV6);
181  if (sid < 0)
182  {
183  /* Mac OS X supports non-privileged ICMP via SOCK_DGRAM type. */
184  sid=socket(AF_INET6,SOCK_DGRAM,IPPROTO_ICMPV6);
185  }
186 #endif
187  if (sid < 0) {
188  ERR_(winediag)("Failed to use ICMPV6 (network ping), this requires special permissions.\n");
190  return INVALID_HANDLE_VALUE;
191  }
192 
193  icp=HeapAlloc(GetProcessHeap(), 0, sizeof(*icp));
194  if (icp==NULL) {
195 #ifdef __REACTOS__
196  closesocket(sid);
197  WSACleanup();
198 #else
199  close(sid);
200 #endif
202  return INVALID_HANDLE_VALUE;
203  }
204  icp->sid=sid;
206  return (HANDLE)icp;
207 }
SOCKET WSAAPI socket(IN INT af, IN INT type, IN INT protocol)
Definition: socklife.c:143
#define ERROR_SUCCESS
Definition: deptool.c:10
#define MAKEWORD(a, b)
Definition: typedefs.h:247
#define ERR_(ch,...)
Definition: debug.h:156
#define closesocket
Definition: precomp.h:57
INT WSAAPI WSACleanup(VOID)
Definition: startup.c:60
#define INVALID_HANDLE_VALUE
Definition: compat.h:399
FT_UInt sid
Definition: cffcmap.c:139
#define IP_NO_RESOURCES
Definition: ticonsts.h:59
#define SOCK_RAW
Definition: winsock.h:337
#define ERROR_ACCESS_DENIED
Definition: compat.h:87
INT WINAPI WSAStartup(IN WORD wVersionRequested, OUT LPWSADATA lpWSAData)
Definition: startup.c:113
smooth NULL
Definition: ftsmooth.c:416
#define AF_INET6
Definition: winsock.h:369
unsigned char OptionsSize
Definition: ipexport.h:36
Definition: icmp.c:118
#define GetProcessHeap()
Definition: compat.h:403
PVOID WINAPI HeapAlloc(HANDLE, DWORD, SIZE_T)
#define IP_OPTS_UNKNOWN
Definition: icmp.c:123
#define SetLastError(x)
Definition: compat.h:417
#define close
Definition: acwin.h:98
int sid
Definition: icmp.c:119
IP_OPTION_INFORMATION default_opts
Definition: icmp.c:120
#define SOCK_DGRAM
Definition: winsock.h:336

Referenced by RunTraceRoute(), test_Icmp6CreateFile(), test_IcmpCloseHandle(), and wmain().

◆ Icmp6SendEcho2()

DWORD WINAPI Icmp6SendEcho2 ( HANDLE  IcmpHandle,
HANDLE  Event,
PIO_APC_ROUTINE  ApcRoutine,
PVOID  ApcContext,
struct sockaddr_in6 SourceAddress,
struct sockaddr_in6 DestinationAddress,
LPVOID  RequestData,
WORD  RequestSize,
PIP_OPTION_INFORMATION  RequestOptions,
LPVOID  ReplyBuffer,
DWORD  ReplySize,
DWORD  Timeout 
)

Definition at line 213 of file icmp.c.

227 {
228  FIXME("(%p, %p, %p, %p, %p, %p, %p, %d, %p, %p, %d, %d): stub\n", IcmpHandle, Event,
230  RequestSize, RequestOptions, ReplyBuffer, ReplySize, Timeout);
232  return 0;
233 }
_In_opt_ HANDLE _In_opt_ PIO_APC_ROUTINE _In_opt_ PVOID ApcContext
Definition: iofuncs.h:719
#define FIXME(fmt,...)
Definition: debug.h:110
#define SetLastError(x)
Definition: compat.h:417
_In_opt_ HANDLE _In_opt_ PIO_APC_ROUTINE ApcRoutine
Definition: iofuncs.h:719
_Must_inspect_result_ _In_ PFLT_PORT _In_ ULONG _Out_writes_bytes_opt_ ReplyLength PVOID ReplyBuffer
Definition: fltkernel.h:1903
static ULONG Timeout
Definition: ping.c:61
#define ERROR_CALL_NOT_IMPLEMENTED
Definition: compat.h:92
_Must_inspect_result_ typedef _In_ PHYSICAL_ADDRESS _Out_ PPHYSICAL_ADDRESS DestinationAddress
Definition: iotypes.h:1090
_Must_inspect_result_ typedef _In_ PHYSICAL_ADDRESS SourceAddress
Definition: iotypes.h:1090

Referenced by Ping(), and RunTraceRoute().

◆ IcmpCloseHandle()

BOOL WINAPI IcmpCloseHandle ( HANDLE  IcmpHandle)

Definition at line 294 of file icmp.c.

295 {
296  icmp_t* icp=(icmp_t*)IcmpHandle;
297 #ifdef __REACTOS__
298  // REACTOS: Added a check for NULL handle, CORE-10707
299  if (IcmpHandle==INVALID_HANDLE_VALUE || IcmpHandle==NULL) {
300 #else
301  if (IcmpHandle==INVALID_HANDLE_VALUE) {
302 #endif
303  /* FIXME: in fact win98 seems to ignore the handle value !!! */
305  return FALSE;
306  }
307 
308 #ifdef __REACTOS__
309  shutdown(icp->sid,2);
310 #else
311  if (icp->sid >= 0) close(icp->sid);
312 #endif
313  HeapFree(GetProcessHeap (), 0, icp);
314 #ifdef __REACTOS__
315  WSACleanup();
316 #endif
317  return TRUE;
318 }
#define TRUE
Definition: types.h:120
#define ERROR_INVALID_HANDLE
Definition: compat.h:88
INT WSAAPI WSACleanup(VOID)
Definition: startup.c:60
#define INVALID_HANDLE_VALUE
Definition: compat.h:399
smooth NULL
Definition: ftsmooth.c:416
Definition: icmp.c:118
#define GetProcessHeap()
Definition: compat.h:403
INT WSAAPI shutdown(IN SOCKET s, IN INT how)
Definition: sockctrl.c:506
#define SetLastError(x)
Definition: compat.h:417
#define close
Definition: acwin.h:98
int sid
Definition: icmp.c:119
#define HeapFree(x, y, z)
Definition: compat.h:402

Referenced by RunTraceRoute(), test_Icmp6CreateFile(), test_IcmpCloseHandle(), test_IcmpCreateFile(), test_IcmpSendEcho(), and wmain().

◆ IcmpCreateFile()

HANDLE WINAPI IcmpCreateFile ( VOID  )

Definition at line 239 of file icmp.c.

240 {
241 #ifndef __REACTOS__
242  static int once;
243 #endif
244  icmp_t* icp;
245 #ifdef __REACTOS__
246  int sid;
247  WSADATA wsaData;
248 
249  if (WSAStartup(MAKEWORD(2, 2), &wsaData) != ERROR_SUCCESS)
250  {
251  ERR_(winediag)("Failed to use ICMPV6 (network ping), this requires special permissions.\n");
252  return INVALID_HANDLE_VALUE;
253  }
255  if (sid < 0) {
256  ERR_(winediag)("Failed to use ICMP (network ping), this requires special permissions.\n");
258  return INVALID_HANDLE_VALUE;
259  }
260 #else
261 
263  if (sid < 0)
264  {
265  /* Mac OS X supports non-privileged ICMP via SOCK_DGRAM type. */
267  }
268  if (sid < 0 && !once++) {
269  FIXME_(winediag)("Failed to use ICMP (network ping), this requires special permissions.\n");
270  FIXME_(winediag)("Falling back to system 'ping' command as a workaround.\n");
271  }
272 #endif
273 
274  icp=HeapAlloc(GetProcessHeap(), 0, sizeof(*icp));
275  if (icp==NULL) {
276 #ifdef __REACTOS__
277  closesocket(sid);
278  WSACleanup();
279 #else
280  if (sid >= 0) close(sid);
281 #endif
283  return INVALID_HANDLE_VALUE;
284  }
285  icp->sid=sid;
287  return (HANDLE)icp;
288 }
SOCKET WSAAPI socket(IN INT af, IN INT type, IN INT protocol)
Definition: socklife.c:143
#define ERROR_SUCCESS
Definition: deptool.c:10
#define MAKEWORD(a, b)
Definition: typedefs.h:247
#define ERR_(ch,...)
Definition: debug.h:156
#define closesocket
Definition: precomp.h:57
INT WSAAPI WSACleanup(VOID)
Definition: startup.c:60
#define INVALID_HANDLE_VALUE
Definition: compat.h:399
FT_UInt sid
Definition: cffcmap.c:139
#define IP_NO_RESOURCES
Definition: ticonsts.h:59
#define SOCK_RAW
Definition: winsock.h:337
#define ERROR_ACCESS_DENIED
Definition: compat.h:87
#define FIXME_(x)
Definition: compat.h:67
INT WINAPI WSAStartup(IN WORD wVersionRequested, OUT LPWSADATA lpWSAData)
Definition: startup.c:113
smooth NULL
Definition: ftsmooth.c:416
unsigned char OptionsSize
Definition: ipexport.h:36
Definition: icmp.c:118
#define GetProcessHeap()
Definition: compat.h:403
PVOID WINAPI HeapAlloc(HANDLE, DWORD, SIZE_T)
#define IP_OPTS_UNKNOWN
Definition: icmp.c:123
#define SetLastError(x)
Definition: compat.h:417
#define close
Definition: acwin.h:98
int sid
Definition: icmp.c:119
IP_OPTION_INFORMATION default_opts
Definition: icmp.c:120
#define AF_INET
Definition: tcpip.h:117
#define SOCK_DGRAM
Definition: winsock.h:336

Referenced by RunTraceRoute(), test_IcmpCloseHandle(), test_IcmpCreateFile(), test_IcmpSendEcho(), and wmain().

◆ IcmpSendEcho()

DWORD WINAPI IcmpSendEcho ( HANDLE  IcmpHandle,
IPAddr  DestinationAddress,
LPVOID  RequestData,
WORD  RequestSize,
PIP_OPTION_INFORMATION  RequestOptions,
LPVOID  ReplyBuffer,
DWORD  ReplySize,
DWORD  Timeout 
)

Definition at line 591 of file icmp.c.

601 {
602  icmp_t* icp=(icmp_t*)IcmpHandle;
603  unsigned char* reqbuf;
604  int reqsize;
605 
606  struct icmp_echo_reply* ier;
607  struct ip* ip_header;
608  struct icmp* icmp_header;
609  char* endbuf;
610  int ip_header_len;
611  int maxlen;
612 #ifdef __REACTOS__
613  fd_set fdr;
614  struct timeval timeout;
615 #else
616  struct pollfd fdr;
617 #endif
618  DWORD send_time,recv_time;
619  struct sockaddr_in addr;
620  socklen_t addrlen;
621  unsigned short id,seq,cksum;
622  int res;
623 
624  if (IcmpHandle==INVALID_HANDLE_VALUE) {
625  /* FIXME: in fact win98 seems to ignore the handle value !!! */
627  return 0;
628  }
629 
630 #ifdef __REACTOS__
631  if (ReplySize<sizeof(ICMP_ECHO_REPLY)) {
633  return 0;
634  }
635 
636  if (ReplySize-RequestSize<sizeof(ICMP_ECHO_REPLY)) {
638  return 0;
639  }
640 
641  if (!ReplyBuffer) {
643  return 0;
644  }
645 
646  if (Timeout == 0 || Timeout == -1) {
648 #else
649  if (ReplySize<sizeof(ICMP_ECHO_REPLY)+ICMP_MINLEN) {
651 #endif
652  return 0;
653  }
654  /* check the request size against SO_MAX_MSG_SIZE using getsockopt */
655 
656  if (!DestinationAddress) {
658  return 0;
659  }
660 
661 #ifndef __REACTOS__
662  if (icp->sid < 0) {
663  WARN("using system ping command since SOCK_RAW was not supported.\n");
664  return system_icmp(DestinationAddress, RequestData, RequestSize,
665  RequestOptions, ReplyBuffer, ReplySize, Timeout);
666  }
667 #endif
668 
669  /* Prepare the request */
670 #ifdef __REACTOS__
671  id = GetCurrentProcessId() & 0xFFFF;
672 #else
673  id=getpid() & 0xFFFF;
674 #endif
675  seq=InterlockedIncrement(&icmp_sequence) & 0xFFFF;
676 
677 #ifdef __REACTOS__
678  reqsize=ICMP_MINLEN;
679  if (RequestData && RequestSize > 0)
680  reqsize += RequestSize;
681 #else
682  reqsize=ICMP_MINLEN+RequestSize;
683 #endif
684  reqbuf=HeapAlloc(GetProcessHeap(), 0, reqsize);
685  if (reqbuf==NULL) {
687  return 0;
688  }
689 
690  icmp_header=(struct icmp*)reqbuf;
691  icmp_header->icmp_type=ICMP_ECHO;
692  icmp_header->icmp_code=0;
693  icmp_header->icmp_cksum=0;
694  icmp_header->icmp_id=id;
695  icmp_header->icmp_seq=seq;
696 #ifdef __REACTOS__
697  if (RequestData && RequestSize > 0)
698  memcpy(reqbuf+ICMP_MINLEN, RequestData, RequestSize);
699 #else
700  memcpy(reqbuf+ICMP_MINLEN, RequestData, RequestSize);
701 #endif
702  icmp_header->icmp_cksum=cksum=in_cksum((u_short*)reqbuf,reqsize);
703 
704  addr.sin_family=AF_INET;
705  addr.sin_addr.s_addr=DestinationAddress;
706  addr.sin_port=0;
707 
708  if (RequestOptions!=NULL) {
709  int val;
711  socklen_t len;
712  /* Before we mess with the options, get the default values */
713  len=sizeof(val);
714  getsockopt(icp->sid,IPPROTO_IP,IP_TTL,(char *)&val,&len);
715  icp->default_opts.Ttl=val;
716 
717  len=sizeof(val);
718  getsockopt(icp->sid,IPPROTO_IP,IP_TOS,(char *)&val,&len);
719  icp->default_opts.Tos=val;
720  /* FIXME: missing: handling of IP 'flags', and all the other options */
721  }
722 
723  val=RequestOptions->Ttl;
724  setsockopt(icp->sid,IPPROTO_IP,IP_TTL,(char *)&val,sizeof(val));
725  val=RequestOptions->Tos;
726  setsockopt(icp->sid,IPPROTO_IP,IP_TOS,(char *)&val,sizeof(val));
727  /* FIXME: missing: handling of IP 'flags', and all the other options */
728 
730  } else if (icp->default_opts.OptionsSize==IP_OPTS_CUSTOM) {
731  int val;
732 
733  /* Restore the default options */
734  val=icp->default_opts.Ttl;
735  setsockopt(icp->sid,IPPROTO_IP,IP_TTL,(char *)&val,sizeof(val));
736  val=icp->default_opts.Tos;
737  setsockopt(icp->sid,IPPROTO_IP,IP_TOS,(char *)&val,sizeof(val));
738  /* FIXME: missing: handling of IP 'flags', and all the other options */
739 
741  }
742 
743  /* Get ready for receiving the reply
744  * Do it before we send the request to minimize the risk of introducing delays
745  */
746 #ifdef __REACTOS__
747  FD_ZERO(&fdr);
748  FD_SET(icp->sid,&fdr);
749  timeout.tv_sec=Timeout/1000;
750  timeout.tv_usec=(Timeout % 1000)*1000;
751 #else
752  fdr.fd = icp->sid;
753  fdr.events = POLLIN;
754 #endif
755  addrlen=sizeof(addr);
756  ier=ReplyBuffer;
757 #ifdef __REACTOS__
758  endbuf=((char *) ReplyBuffer)+ReplySize;
759  maxlen=sizeof(struct ip)+ICMP_MINLEN+RequestSize;
760 #else
761  ip_header=(struct ip *) ((char *) ReplyBuffer+sizeof(ICMP_ECHO_REPLY));
762  endbuf=(char *) ReplyBuffer+ReplySize;
763  maxlen=ReplySize-sizeof(ICMP_ECHO_REPLY);
764 #endif
765 
766  /* Send the packet */
767  TRACE("Sending %d bytes (RequestSize=%d) to %s\n", reqsize, RequestSize, inet_ntoa(addr.sin_addr));
768 #if 0
769  if (TRACE_ON(icmp)){
770  unsigned char* buf=(unsigned char*)reqbuf;
771  int i;
772  printf("Output buffer:\n");
773  for (i=0;i<reqsize;i++)
774  printf("%2x,", buf[i]);
775  printf("\n");
776  }
777 #endif
778 
779  send_time = GetTickCount();
780 #ifdef __REACTOS__
781  res=sendto(icp->sid, (const char*)reqbuf, reqsize, 0, (struct sockaddr*)&addr, sizeof(addr));
782 #else
783  res=sendto(icp->sid, reqbuf, reqsize, 0, (struct sockaddr*)&addr, sizeof(addr));
784 #endif
785  HeapFree(GetProcessHeap (), 0, reqbuf);
786  if (res<0) {
787 #ifdef __REACTOS__
788  DWORD dwBestIfIndex;
789  IPAddr IP4Addr;
790 
791  ZeroMemory(&ier->Address, sizeof(ier->Address));
792 
793  if (GetBestInterface(addr.sin_addr.s_addr, &dwBestIfIndex) == NO_ERROR &&
794  GetIPv4ByIndex(dwBestIfIndex, &IP4Addr))
795  {
796  memcpy(&ier->Address, &IP4Addr, sizeof(IP4Addr));
797  }
798 
800  ier->Status = IP_PACKET_TOO_BIG;
801  else {
802  switch (WSAGetLastError()) {
803  case WSAENETUNREACH:
805  break;
806  case WSAEHOSTUNREACH:
808  break;
809  default:
810  TRACE("unknown error: errno=%d\n",WSAGetLastError());
811  ier->Status = IP_GENERAL_FAILURE;
812  ZeroMemory(&ier->Address, sizeof(ier->Address));
813  }
814  }
815  return 1;
816 #else
817  if (errno==EMSGSIZE)
819  else {
820  switch (errno) {
821  case ENETUNREACH:
823  break;
824  case EHOSTUNREACH:
826  break;
827  default:
828  TRACE("unknown error: errno=%d\n",errno);
830  }
831  }
832  return 0;
833 #endif
834  }
835 
836  /* Get the reply */
837 #ifdef __REACTOS__
838  ip_header=HeapAlloc(GetProcessHeap(), 0, maxlen);
839 #endif
840  ip_header_len=0; /* because gcc was complaining */
841 #ifdef __REACTOS__
842  while ((res=select(icp->sid+1,&fdr,NULL,NULL,&timeout))>0) {
843 #else
844  while (poll(&fdr,1,Timeout)>0) {
845 #endif
846  recv_time = GetTickCount();
847 #ifdef __REACTOS__
848  res=recvfrom(icp->sid, (char*)ip_header, maxlen, 0, (struct sockaddr*)&addr,(int*)&addrlen);
849 #else
850  res=recvfrom(icp->sid, (char*)ip_header, maxlen, 0, (struct sockaddr*)&addr,&addrlen);
851 #endif
852  TRACE("received %d bytes from %s\n",res, inet_ntoa(addr.sin_addr));
854 #ifdef __REACTOS__
855  if (res < 0)
856  break;
857 #endif
858 
859  /* Check whether we should ignore this packet */
860  if ((ip_header->ip_p==IPPROTO_ICMP) && (res>=sizeof(struct ip)+ICMP_MINLEN)) {
861  ip_header_len=ip_header->ip_hl << 2;
862  icmp_header=(struct icmp*)(((char*)ip_header)+ip_header_len);
863  TRACE("received an ICMP packet of type,code=%d,%d\n",icmp_header->icmp_type,icmp_header->icmp_code);
864  if (icmp_header->icmp_type==ICMP_ECHOREPLY) {
865  if ((icmp_header->icmp_id==id) && (icmp_header->icmp_seq==seq))
866  ier->Status=IP_SUCCESS;
867  } else {
868  switch (icmp_header->icmp_type) {
869  case ICMP_UNREACH:
870  switch (icmp_header->icmp_code) {
871  case ICMP_UNREACH_HOST:
872 #ifdef ICMP_UNREACH_HOST_UNKNOWN
874 #endif
875 #ifdef ICMP_UNREACH_ISOLATED
877 #endif
878 #ifdef ICMP_UNREACH_HOST_PROHIB
880 #endif
881 #ifdef ICMP_UNREACH_TOSHOST
883 #endif
885  break;
886  case ICMP_UNREACH_PORT:
888  break;
891  break;
893  ier->Status=IP_BAD_ROUTE;
894  break;
895  default:
897  }
898  break;
899  case ICMP_TIMXCEED:
900  if (icmp_header->icmp_code==ICMP_TIMXCEED_REASS)
902  else
904  break;
905  case ICMP_PARAMPROB:
907  break;
908  case ICMP_SOURCEQUENCH:
910  break;
911  }
912  if (ier->Status!=IP_REQ_TIMED_OUT) {
913  struct ip* rep_ip_header;
914  struct icmp* rep_icmp_header;
915  /* The ICMP header size of all the packets we accept is the same */
916  rep_ip_header=(struct ip*)(((char*)icmp_header)+ICMP_MINLEN);
917  rep_icmp_header=(struct icmp*)(((char*)rep_ip_header)+(rep_ip_header->ip_hl << 2));
918 
919  /* Make sure that this is really a reply to our packet */
920  if (ip_header_len+ICMP_MINLEN+(rep_ip_header->ip_hl << 2)+ICMP_MINLEN>ip_header->ip_len) {
922  } else if ((rep_icmp_header->icmp_type!=ICMP_ECHO) ||
923  (rep_icmp_header->icmp_code!=0) ||
924  (rep_icmp_header->icmp_id!=id) ||
925  /* windows doesn't check this checksum, else tracert */
926  /* behind a Linux 2.2 masquerading firewall would fail*/
927  /* (rep_icmp_header->icmp_cksum!=cksum) || */
928  (rep_icmp_header->icmp_seq!=seq)) {
929  /* This was not a reply to one of our packets after all */
930  TRACE("skipping type,code=%d,%d id,seq=%d,%d cksum=%d\n",
931  rep_icmp_header->icmp_type,rep_icmp_header->icmp_code,
932  rep_icmp_header->icmp_id,rep_icmp_header->icmp_seq,
933  rep_icmp_header->icmp_cksum);
934  TRACE("expected type,code=8,0 id,seq=%d,%d cksum=%d\n",
935  id,seq,
936  cksum);
938  }
939  }
940  }
941  }
942 
943  if (ier->Status==IP_REQ_TIMED_OUT) {
944  /* This packet was not for us.
945  * Decrease the timeout so that we don't enter an endless loop even
946  * if we get flooded with ICMP packets that are not for us.
947  */
948 #ifdef __REACTOS__
949  int t = Timeout - (recv_time - send_time);
950  if (t < 0) t = 0;
951  timeout.tv_sec = t / 1000;
952  timeout.tv_usec = (t % 1000) * 1000;
953  FD_ZERO(&fdr);
954  FD_SET(icp->sid, &fdr);
955 #else
956  DWORD t = (recv_time - send_time);
957  if (Timeout > t) Timeout -= t;
958  else Timeout = 0;
959 #endif
960  continue;
961  } else {
962  /* This is a reply to our packet */
963  memcpy(&ier->Address,&ip_header->ip_src,sizeof(IPAddr));
964  /* Status is already set */
965  ier->RoundTripTime= recv_time - send_time;
966  ier->DataSize=res-ip_header_len-ICMP_MINLEN;
967  ier->Reserved=0;
968  ier->Data=endbuf-ier->DataSize;
969  memmove(ier->Data,((char*)ip_header)+ip_header_len+ICMP_MINLEN,ier->DataSize);
970  ier->Options.Ttl=ip_header->ip_ttl;
971  ier->Options.Tos=ip_header->ip_tos;
972  ier->Options.Flags=ip_header->ip_off >> 13;
973  ier->Options.OptionsSize=ip_header_len-sizeof(struct ip);
974  if (ier->Options.OptionsSize!=0) {
975  ier->Options.OptionsData=(unsigned char *) ier->Data-ier->Options.OptionsSize;
976  /* FIXME: We are supposed to rearrange the option's 'source route' data */
977  memmove(ier->Options.OptionsData,((char*)ip_header)+ip_header_len,ier->Options.OptionsSize);
978  endbuf=(char*)ier->Options.OptionsData;
979  } else {
980  ier->Options.OptionsData=NULL;
981  endbuf=ier->Data;
982  }
983 
984  /* Prepare for the next packet */
985  ier++;
986 #ifndef __REACTOS__
987  ip_header=(struct ip*)(((char*)ip_header)+sizeof(ICMP_ECHO_REPLY));
988  maxlen=endbuf-(char*)ip_header;
989 #endif
990 
991  /* Check out whether there is more but don't wait this time */
992 #ifdef __REACTOS__
993  timeout.tv_sec=0;
994  timeout.tv_usec=0;
995 #else
996  Timeout=0;
997 #endif
998  }
999 #ifdef __REACTOS__
1000  FD_ZERO(&fdr);
1001  FD_SET(icp->sid,&fdr);
1002 #endif
1003  }
1004 #ifdef __REACTOS__
1005  HeapFree(GetProcessHeap(), 0, ip_header);
1006 #endif
1008  if (res==0)
1009 #ifdef __REACTOS__
1010  {
1011  ier->Status = IP_REQ_TIMED_OUT;
1012 #endif
1014 #ifdef __REACTOS__
1015  }
1016 #endif
1017  TRACE("received %d replies\n",res);
1018  return res;
1019 }
Definition: winsock.h:66
static DWORD system_icmp(IPAddr DestinationAddress, LPVOID RequestData, WORD RequestSize, PIP_OPTION_INFORMATION RequestOptions, LPVOID ReplyBuffer, DWORD ReplySize, DWORD Timeout)
Definition: icmp.c:321
#define IP_TOS
Definition: winsock.h:325
#define IP_BUF_TOO_SMALL
Definition: ipexport.h:103
#define ERROR_INVALID_PARAMETER
Definition: compat.h:91
INT WSAAPI recvfrom(IN SOCKET s, OUT CHAR FAR *buf, IN INT len, IN INT flags, OUT LPSOCKADDR from, IN OUT INT FAR *fromlen)
Definition: recv.c:87
#define memmove(s1, s2, n)
Definition: mkisofs.h:881
#define ICMP_UNREACH_PORT
Definition: ip_icmp.h:138
#define ICMP_TIMXCEED_REASS
Definition: ip_icmp.h:162
unsigned char Tos
Definition: ipexport.h:34
GLenum GLuint GLenum GLsizei const GLchar * buf
Definition: glext.h:7751
#define WARN(fmt,...)
Definition: debug.h:111
#define ERROR_INVALID_HANDLE
Definition: compat.h:88
unsigned short DataSize
Definition: ipexport.h:72
unsigned short Reserved
Definition: ipexport.h:73
DWORD WINAPI GetTickCount(VOID)
Definition: time.c:455
#define ICMP_ECHOREPLY
Definition: ip_icmp.h:133
#define IP_OPTS_DEFAULT
Definition: icmp.c:124
GLdouble GLdouble t
Definition: gl.h:2047
#define INVALID_HANDLE_VALUE
Definition: compat.h:399
#define ZeroMemory
Definition: winbase.h:1642
Definition: dhcpd.h:245
u_char icmp_type
Definition: ip_icmp.h:53
int errno
#define ICMP_PARAMPROB
Definition: ip_icmp.h:163
#define FD_ZERO(set)
Definition: winsock.h:96
#define IP_TTL_EXPIRED_TRANSIT
Definition: ipexport.h:115
#define ICMP_SOURCEQUENCH
Definition: ip_icmp.h:151
#define FD_SET(fd, set)
Definition: winsock.h:89
#define NO_ERROR
Definition: dderror.h:5
u_char icmp_code
Definition: ip_icmp.h:54
#define IP_PARAM_PROBLEM
Definition: ipexport.h:117
static LONG icmp_sequence
Definition: icmp.c:130
#define ICMP_UNREACH_HOST_PROHIB
Definition: ip_icmp.h:145
#define IP_PACKET_TOO_BIG
Definition: ipexport.h:111
unsigned int ip_hl
Definition: dhcpd.h:63
#define ENETUNREACH
Definition: errno.h:112
IPAddr Address
Definition: ipexport.h:69
GLsizei GLenum const GLvoid GLsizei GLenum GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLint GLint GLint GLshort GLshort GLshort GLubyte GLubyte GLubyte GLuint GLuint GLuint GLushort GLushort GLushort GLbyte GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLfloat GLint GLint GLint GLint GLshort GLshort GLshort GLshort GLubyte GLubyte GLubyte GLubyte GLuint GLuint GLuint GLuint GLushort GLushort GLushort GLushort GLboolean const GLdouble const GLfloat const GLint const GLshort const GLbyte const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLdouble const GLfloat const GLfloat const GLint const GLint const GLshort const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort GLenum GLenum GLenum GLfloat GLenum GLint GLenum GLenum GLenum GLfloat GLenum GLenum GLint GLenum GLfloat GLenum GLint GLint GLushort GLenum GLenum GLfloat GLenum GLenum GLint GLfloat const GLubyte GLenum GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLint GLint GLsizei GLsizei GLint GLenum GLenum const GLvoid GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLenum const GLdouble GLenum GLenum const GLfloat GLenum GLenum const GLint GLsizei GLuint GLfloat GLuint GLbitfield GLfloat GLint GLuint GLboolean GLenum GLfloat GLenum GLbitfield GLenum GLfloat GLfloat GLint GLint const GLfloat GLenum GLfloat GLfloat GLint GLint GLfloat GLfloat GLint GLint const GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat const GLdouble const GLfloat const GLdouble const GLfloat GLint i
Definition: glfuncs.h:248
#define IP_OPTS_CUSTOM
Definition: icmp.c:125
Definition: ip_icmp.h:52
INT WSAAPI select(IN INT s, IN OUT LPFD_SET readfds, IN OUT LPFD_SET writefds, IN OUT LPFD_SET exceptfds, IN CONST struct timeval *timeout)
Definition: select.c:41
#define IP_DEST_PORT_UNREACHABLE
Definition: ipexport.h:107
INT WSAAPI setsockopt(IN SOCKET s, IN INT level, IN INT optname, IN CONST CHAR FAR *optval, IN INT optlen)
Definition: sockctrl.c:421
static int in_cksum(u_short *addr, int len)
Definition: icmp.c:132
smooth NULL
Definition: ftsmooth.c:416
ULONG Status
Definition: ipexport.h:70
#define ICMP_TIMXCEED
Definition: ip_icmp.h:160
unsigned char OptionsSize
Definition: ipexport.h:36
#define ICMP_UNREACH_ISOLATED
Definition: ip_icmp.h:143
ULONG IPAddr
Definition: pfhook.h:35
#define inet_ntoa(addr)
Definition: inet.h:100
#define IPPROTO_IP
Definition: winsock.h:255
GLuint GLfloat * val
Definition: glext.h:7180
void * Data
Definition: ipexport.h:74
#define IP_GENERAL_FAILURE
Definition: ipexport.h:127
_CRTIMP int __cdecl getpid(void)
#define TRACE(s)
Definition: solgame.cpp:4
INT WSAAPI WSAGetLastError(VOID)
Definition: dllmain.c:112
#define IP_REQ_TIMED_OUT
Definition: ipexport.h:112
Definition: icmp.c:118
#define GetProcessHeap()
Definition: compat.h:403
#define ICMP_UNREACH_HOST
Definition: ip_icmp.h:136
PVOID WINAPI HeapAlloc(HANDLE, DWORD, SIZE_T)
Definition: dhcpd.h:61
#define ICMP_UNREACH_SRCFAIL
Definition: ip_icmp.h:140
#define IP_BAD_ROUTE
Definition: ipexport.h:114
#define IP_OPTS_UNKNOWN
Definition: icmp.c:123
#define IP_DEST_NET_UNREACHABLE
Definition: ipexport.h:104
int poll(struct pollfd *ufds, int nfds, int timeout)
Definition: adnstest.c:68
unsigned long DWORD
Definition: ntddk_ex.h:95
#define WSAEHOSTUNREACH
Definition: winerror.h:1978
int socklen_t
Definition: tcp.c:35
#define POLLIN
Definition: linux.h:1853
#define SetLastError(x)
Definition: compat.h:417
Definition: linux.h:1867
unsigned short u_short
Definition: types.h:81
#define WSAEMSGSIZE
Definition: winerror.h:1953
unsigned char Ttl
Definition: ipexport.h:33
_Must_inspect_result_ _In_ PFLT_PORT _In_ ULONG _Out_writes_bytes_opt_ ReplyLength PVOID ReplyBuffer
Definition: fltkernel.h:1903
GLenum const GLvoid * addr
Definition: glext.h:9621
#define WSAENETUNREACH
Definition: winerror.h:1964
ULONG RoundTripTime
Definition: ipexport.h:71
#define memcpy(s1, s2, n)
Definition: mkisofs.h:878
GLenum GLsizei len
Definition: glext.h:6722
int sid
Definition: icmp.c:119
INT WSAAPI getsockopt(IN SOCKET s, IN INT level, IN INT optname, OUT CHAR FAR *optval, IN OUT INT FAR *optlen)
Definition: sockctrl.c:271
#define ICMP_UNREACH_PROTOCOL
Definition: ip_icmp.h:137
#define ERROR_INVALID_NETNAME
Definition: winerror.h:717
DWORD WINAPI GetBestInterface(IPAddr dwDestAddr, PDWORD pdwBestIfIndex)
#define ICMP_UNREACH_HOST_UNKNOWN
Definition: ip_icmp.h:142
static ULONG Timeout
Definition: ping.c:61
#define InterlockedIncrement
Definition: armddk.h:53
#define ICMP_UNREACH_TOSHOST
Definition: ip_icmp.h:147
IP_OPTION_INFORMATION default_opts
Definition: icmp.c:120
#define ICMP_ECHO
Definition: ip_icmp.h:157
INT WSAAPI sendto(IN SOCKET s, IN CONST CHAR FAR *buf, IN INT len, IN INT flags, IN CONST struct sockaddr *to, IN INT tolen)
Definition: send.c:82
#define IP_TTL
Definition: winsock.h:324
#define EHOSTUNREACH
Definition: errno.h:124
GLuint res
Definition: glext.h:9613
struct icmp_echo_reply ICMP_ECHO_REPLY
Definition: ipexport.h:80
GLenum GLuint id
Definition: glext.h:5579
#define AF_INET
Definition: tcpip.h:117
#define IP_DEST_PROT_UNREACHABLE
Definition: ipexport.h:106
#define IP_SUCCESS
Definition: ticonsts.h:58
#define EMSGSIZE
Definition: errno.h:97
struct ip_option_information Options
Definition: ipexport.h:75
_Must_inspect_result_ typedef _In_ PHYSICAL_ADDRESS _Out_ PPHYSICAL_ADDRESS DestinationAddress
Definition: iotypes.h:1090
#define ICMP_MINLEN
Definition: ip_icmp.h:118
#define IP_DEST_HOST_UNREACHABLE
Definition: ipexport.h:105
#define TRACE_ON(x)
Definition: compat.h:65
#define ICMP_UNREACH
Definition: ip_icmp.h:134
#define HeapFree(x, y, z)
Definition: compat.h:402
#define IP_SOURCE_QUENCH
Definition: ipexport.h:118
u_short icmp_cksum
Definition: ip_icmp.h:55
#define IP_TTL_EXPIRED_REASSEM
Definition: ipexport.h:116
DWORD WINAPI GetCurrentProcessId(VOID)
Definition: proc.c:1158
#define ERROR_OUTOFMEMORY
Definition: deptool.c:13
#define printf
Definition: config.h:203

Referenced by IcmpSendEcho2(), IcmpSendEcho2Ex(), and test_IcmpSendEcho().

◆ IcmpSendEcho2()

DWORD WINAPI IcmpSendEcho2 ( HANDLE  IcmpHandle,
HANDLE  Event,
PIO_APC_ROUTINE  ApcRoutine,
PVOID  ApcContext,
IPAddr  DestinationAddress,
LPVOID  RequestData,
WORD  RequestSize,
PIP_OPTION_INFORMATION  RequestOptions,
LPVOID  ReplyBuffer,
DWORD  ReplySize,
DWORD  Timeout 
)

Definition at line 1024 of file icmp.c.

1037 {
1038  TRACE("(%p, %p, %p, %p, %08x, %p, %d, %p, %p, %d, %d): stub\n", IcmpHandle,
1040  RequestSize, RequestOptions, ReplyBuffer, ReplySize, Timeout);
1041 
1042  if (Event)
1043  {
1044  FIXME("unsupported for events\n");
1045  return 0;
1046  }
1047  if (ApcRoutine)
1048  {
1049  FIXME("unsupported for APCs\n");
1050  return 0;
1051  }
1052  return IcmpSendEcho(IcmpHandle, DestinationAddress, RequestData,
1053  RequestSize, RequestOptions, ReplyBuffer, ReplySize, Timeout);
1054 }
DWORD WINAPI IcmpSendEcho(HANDLE IcmpHandle, IPAddr DestinationAddress, LPVOID RequestData, WORD RequestSize, PIP_OPTION_INFORMATION RequestOptions, LPVOID ReplyBuffer, DWORD ReplySize, DWORD Timeout)
Definition: icmp.c:591
_In_opt_ HANDLE _In_opt_ PIO_APC_ROUTINE _In_opt_ PVOID ApcContext
Definition: iofuncs.h:719
#define FIXME(fmt,...)
Definition: debug.h:110
#define TRACE(s)
Definition: solgame.cpp:4
_In_opt_ HANDLE _In_opt_ PIO_APC_ROUTINE ApcRoutine
Definition: iofuncs.h:719
_Must_inspect_result_ _In_ PFLT_PORT _In_ ULONG _Out_writes_bytes_opt_ ReplyLength PVOID ReplyBuffer
Definition: fltkernel.h:1903
static ULONG Timeout
Definition: ping.c:61
_Must_inspect_result_ typedef _In_ PHYSICAL_ADDRESS _Out_ PPHYSICAL_ADDRESS DestinationAddress
Definition: iotypes.h:1090

Referenced by Ping(), and RunTraceRoute().

◆ IcmpSendEcho2Ex()

DWORD WINAPI IcmpSendEcho2Ex ( HANDLE  IcmpHandle,
HANDLE  Event,
PIO_APC_ROUTINE  ApcRoutine,
PVOID  ApcContext,
IPAddr  SourceAddress,
IPAddr  DestinationAddress,
LPVOID  RequestData,
WORD  RequestSize,
PIP_OPTION_INFORMATION  RequestOptions,
LPVOID  ReplyBuffer,
DWORD  ReplySize,
DWORD  Timeout 
)

Definition at line 1059 of file icmp.c.

1073 {
1074  TRACE("(%p, %p, %p, %p, %08x, %08x, %p, %d, %p, %p, %d, %d): stub\n", IcmpHandle,
1076  RequestSize, RequestOptions, ReplyBuffer, ReplySize, Timeout);
1077 
1078  if (Event)
1079  {
1080  FIXME("unsupported for events\n");
1081  return 0;
1082  }
1083  if (ApcRoutine)
1084  {
1085  FIXME("unsupported for APCs\n");
1086  return 0;
1087  }
1088  if (SourceAddress)
1089  {
1090  FIXME("unsupported for source addresses\n");
1091  return 0;
1092  }
1093 
1094  return IcmpSendEcho(IcmpHandle, DestinationAddress, RequestData,
1095  RequestSize, RequestOptions, ReplyBuffer, ReplySize, Timeout);
1096 }
DWORD WINAPI IcmpSendEcho(HANDLE IcmpHandle, IPAddr DestinationAddress, LPVOID RequestData, WORD RequestSize, PIP_OPTION_INFORMATION RequestOptions, LPVOID ReplyBuffer, DWORD ReplySize, DWORD Timeout)
Definition: icmp.c:591
_In_opt_ HANDLE _In_opt_ PIO_APC_ROUTINE _In_opt_ PVOID ApcContext
Definition: iofuncs.h:719
#define FIXME(fmt,...)
Definition: debug.h:110
#define TRACE(s)
Definition: solgame.cpp:4
_In_opt_ HANDLE _In_opt_ PIO_APC_ROUTINE ApcRoutine
Definition: iofuncs.h:719
_Must_inspect_result_ _In_ PFLT_PORT _In_ ULONG _Out_writes_bytes_opt_ ReplyLength PVOID ReplyBuffer
Definition: fltkernel.h:1903
static ULONG Timeout
Definition: ping.c:61
_Must_inspect_result_ typedef _In_ PHYSICAL_ADDRESS _Out_ PPHYSICAL_ADDRESS DestinationAddress
Definition: iotypes.h:1090
_Must_inspect_result_ typedef _In_ PHYSICAL_ADDRESS SourceAddress
Definition: iotypes.h:1090

◆ in_cksum()

static int in_cksum ( u_short addr,
int  len 
)
static

Definition at line 132 of file icmp.c.

133 {
134  int nleft=len;
135  u_short *w = addr;
136  int sum = 0;
137  u_short answer = 0;
138 
139  while (nleft > 1) {
140  sum += *w++;
141  nleft -= 2;
142  }
143 
144  if (nleft == 1) {
145  *(u_char *)(&answer) = *(u_char *)w;
146  sum += answer;
147  }
148 
149  sum = (sum >> 16) + (sum & 0xffff);
150  sum += (sum >> 16);
151  answer = ~sum;
152  return(answer);
153 }
GLubyte GLubyte GLubyte GLubyte w
Definition: glext.h:6102
static int sum(int x_, int y_)
Definition: ptr2_test.cpp:35
unsigned short u_short
Definition: types.h:81
GLenum const GLvoid * addr
Definition: glext.h:9621
GLenum GLsizei len
Definition: glext.h:6722
UCHAR u_char
Definition: types.h:80

Referenced by IcmpSendEcho().

◆ system_icmp()

static DWORD system_icmp ( IPAddr  DestinationAddress,
LPVOID  RequestData,
WORD  RequestSize,
PIP_OPTION_INFORMATION  RequestOptions,
LPVOID  ReplyBuffer,
DWORD  ReplySize,
DWORD  Timeout 
)
static

Definition at line 321 of file icmp.c.

330 {
331 #ifdef HAVE_FORK
332  ICMP_ECHO_REPLY *reply = ReplyBuffer;
333  char ntoa_buffer[16]; /* 4*3 digits + 3 '.' + 1 '\0' */
334  char size_buffer[6]; /* 5 digits + '\0' */
335  char tos_buffer[4]; /* 3 digits + '\0' */
336  char ttl_buffer[4]; /* 3 digits + '\0' */
337  char time_buffer[11]; /* 10 digits + '\0' */
338  int i, pos, res, status, argc;
339  const char *argv[20];
340  struct in_addr addr;
341  int pipe_out[2];
342  pid_t pid, wpid;
343  char *ptr, *eol;
344  char buf[127];
345 
346  /* Assemble the ping commandline */
347  argc = 0;
348  argv[argc++] = "ping";
349  argv[argc++] = "-c"; /* only send a single ping */
350  argv[argc++] = "1";
351  argv[argc++] = "-n"; /* numeric output only */
352  argv[argc++] = "-s"; /* request size */
353  sprintf(size_buffer, "%u", (RequestSize >= 16) ? RequestSize : 16);
354  argv[argc++] = size_buffer;
355  argv[argc++] = "-W"; /* timeout */
356 #ifdef __linux__
357  /* The linux 'ping' utlity expects a time in seconds */
358  Timeout = (Timeout + 999) / 1000;
359 #endif
360  sprintf(time_buffer, "%u", Timeout);
361  argv[argc++] = time_buffer;
362 
363  if (RequestOptions)
364  {
365  #ifdef __linux__
366  argv[argc++] = "-Q"; /* tos option */
367  #else
368  argv[argc++] = "-z"; /* tos option */
369  #endif
370  sprintf(tos_buffer, "%u", RequestOptions->Tos);
371  argv[argc++] = tos_buffer;
372  #ifdef __linux__
373  /* TTL can only be specified for multicast addresses on FreeBSD/MacOS */
374  argv[argc++] = "-t"; /* ttl option */
375  sprintf(ttl_buffer, "%u", RequestOptions->Ttl);
376  argv[argc++] = ttl_buffer;
377  #endif
378  }
379 
380  addr.s_addr = DestinationAddress;
381  if (!(ptr = inet_ntoa(addr)))
382  {
384  return 0;
385  }
386  strcpy(ntoa_buffer, ptr);
387  argv[argc++] = ntoa_buffer;
388  argv[argc] = NULL;
389 
390  /* Dump commandline for debugging purposes */
391  TRACE("Ping commandline: ");
392  for (i = 0; i < argc; i++)
393  {
394  TRACE("%s ", debugstr_a(argv[i]));
395  }
396  TRACE("\n");
397 
398  /* Prefill the reply struct with fallback values */
399  memset(reply, 0, sizeof(*reply));
400  reply->Address = DestinationAddress;
401  reply->RoundTripTime = 40;
402  reply->Options.Ttl = 120;
403 
404  /* Create communication pipes */
405 #ifdef HAVE_PIPE2
406  if (pipe2(pipe_out, O_CLOEXEC) < 0)
407 #endif
408  {
409  if (pipe(pipe_out) < 0)
410  {
412  return 0;
413  }
414  fcntl(pipe_out[0], F_SETFD, FD_CLOEXEC);
415  fcntl(pipe_out[1], F_SETFD, FD_CLOEXEC);
416  }
417 
418  /* Fork child process */
419  pid = fork();
420  if (pid == -1)
421  {
422  close(pipe_out[0]);
423  close(pipe_out[1]);
425  return 0;
426  }
427 
428  /* Child process */
429  if (pid == 0)
430  {
431  static char lang_env[] = "LANG=C";
432 
433  dup2(pipe_out[1], 1);
434  close(pipe_out[0]);
435  close(pipe_out[1]);
436  close(0);
437  close(2);
438 
439  putenv(lang_env);
440  execvp(argv[0], (char **)argv);
441  _exit(1);
442  }
443 
444  close(pipe_out[1]);
445 
446  /* Wait for child and read output */
447  pos = 0;
448  do
449  {
450  if (pos >= sizeof(buf) - 1)
451  {
452  ERR("line too long, dropping buffer\n");
453  pos = 0;
454  }
455 
456  /* read next block */
457  do
458  {
459  res = read(pipe_out[0], &buf[pos], (sizeof(buf) - 1) - pos);
460  }
461  while (res < 0 && errno == EINTR);
462  if (res < 0)
463  {
464  ERR("read failed: %s\n", strerror(errno));
465  break;
466  }
467 
468  pos += res;
469  while (pos)
470  {
471  eol = memchr(buf, '\n', pos);
472  if (!eol) break;
473  *eol = 0;
474 
475  TRACE("Received line: %s\n", debugstr_a(buf));
476 
477  /* Interpret address */
478  if ((ptr = strstr(buf, "from ")))
479  {
480  int a, b, c, d;
481  if (sscanf(ptr + 5, "%u.%u.%u.%u", &a, &b, &c, &d) >= 4)
482  {
483  reply->Address = a | (b << 8) | (c << 16) | (d << 24);
484  addr.s_addr = reply->Address;
485  TRACE("Got address %s\n", inet_ntoa(addr));
486  }
487  }
488 
489  /* Interpret ttl */
490  if ((ptr = strstr(buf, "ttl=")))
491  {
492  int val;
493  if (sscanf(ptr + 4, "%u", &val) >= 1)
494  {
495  reply->Options.Ttl = val;
496  TRACE("Got ttl %u\n", val);
497  }
498  }
499 
500  /* Interpret time */
501  if ((ptr = strstr(buf, "time=")))
502  {
503  float val;
504  if (sscanf(ptr + 5, "%f", &val) >= 1)
505  {
506  reply->RoundTripTime = (unsigned int)(val + 0.5);
507  TRACE("Got rtt = %u\n", reply->RoundTripTime);
508  }
509  }
510 
511  memmove(buf, eol + 1, pos - (eol + 1 - buf));
512  pos -= (eol + 1 - buf);
513  }
514  }
515  while (res > 0);
516  close(pipe_out[0]);
517 
518  /* reap the child process */
519  do
520  {
521  wpid = waitpid(pid, &status, 0);
522  }
523  while (wpid < 0 && errno == EINTR);
524 
525  /* fill out remaining struct fields */
526  if (wpid >= 0 && WIFEXITED(status) && WEXITSTATUS(status) == 0)
527  {
528  if (ReplySize < RequestSize + sizeof(*reply))
529  {
530  reply->Status = IP_BUF_TOO_SMALL;
531  reply->DataSize = 0;
532  reply->Data = NULL;
533  }
534  else
535  {
536  reply->Status = 0;
537  reply->DataSize = RequestSize;
538  reply->Data = (char *)reply + sizeof(*reply);
539  memcpy(reply->Data, RequestData, RequestSize);
540  }
541  return 1;
542  }
543 
545  return 0;
546 #else
547  ERR("no fork support on this platform\n");
549  return 0;
550 #endif
551 }
#define IP_BUF_TOO_SMALL
Definition: ipexport.h:103
#define ERROR_INVALID_PARAMETER
Definition: compat.h:91
static int argc
Definition: ServiceArgs.c:12
_In_ ULONG_PTR _In_ ULONG _Out_ ULONG_PTR * pid
Definition: winddi.h:3835
#define memmove(s1, s2, n)
Definition: mkisofs.h:881
_Check_return_ _CRTIMP int __cdecl putenv(_In_z_ const char *_EnvString)
#define memchr(s, c, n)
Definition: mkisofs.h:875
unsigned char Tos
Definition: ipexport.h:34
GLenum GLuint GLenum GLsizei const GLchar * buf
Definition: glext.h:7751
char * strstr(char *String1, char *String2)
Definition: utclib.c:653
#define EINTR
Definition: acclib.h:80
unsigned short DataSize
Definition: ipexport.h:72
DWORD pid_t
Definition: types.h:91
int errno
#define argv
Definition: mplay32.c:18
const char * strerror(int err)
Definition: compat_str.c:23
#define sprintf(buf, format,...)
Definition: sprintf.c:55
IPAddr Address
Definition: ipexport.h:69
GLsizei GLenum const GLvoid GLsizei GLenum GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLint GLint GLint GLshort GLshort GLshort GLubyte GLubyte GLubyte GLuint GLuint GLuint GLushort GLushort GLushort GLbyte GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLfloat GLint GLint GLint GLint GLshort GLshort GLshort GLshort GLubyte GLubyte GLubyte GLubyte GLuint GLuint GLuint GLuint GLushort GLushort GLushort GLushort GLboolean const GLdouble const GLfloat const GLint const GLshort const GLbyte const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLdouble const GLfloat const GLfloat const GLint const GLint const GLshort const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort GLenum GLenum GLenum GLfloat GLenum GLint GLenum GLenum GLenum GLfloat GLenum GLenum GLint GLenum GLfloat GLenum GLint GLint GLushort GLenum GLenum GLfloat GLenum GLenum GLint GLfloat const GLubyte GLenum GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLint GLint GLsizei GLsizei GLint GLenum GLenum const GLvoid GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLenum const GLdouble GLenum GLenum const GLfloat GLenum GLenum const GLint GLsizei GLuint GLfloat GLuint GLbitfield GLfloat GLint GLuint GLboolean GLenum GLfloat GLenum GLbitfield GLenum GLfloat GLfloat GLint GLint const GLfloat GLenum GLfloat GLfloat GLint GLint GLfloat GLfloat GLint GLint const GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat const GLdouble const GLfloat const GLdouble const GLfloat GLint i
Definition: glfuncs.h:248
#define a
Definition: ke_i.h:78
static PVOID ptr
Definition: dispmode.c:27
smooth NULL
Definition: ftsmooth.c:416
ULONG Status
Definition: ipexport.h:70
_Check_return_ _CRTIMP int __cdecl sscanf(_In_z_ const char *_Src, _In_z_ _Scanf_format_string_ const char *_Format,...)
void _exit(int exitcode)
Definition: _exit.c:25
_Check_return_ _CRTIMP int __cdecl dup2(_In_ int _FileHandleSrc, _In_ int _FileHandleDst)
#define b
Definition: ke_i.h:79
#define inet_ntoa(addr)
Definition: inet.h:100
GLuint GLfloat * val
Definition: glext.h:7180
void * Data
Definition: ipexport.h:74
GLboolean GLboolean GLboolean b
Definition: glext.h:6204
#define TRACE(s)
Definition: solgame.cpp:4
#define IP_REQ_TIMED_OUT
Definition: ipexport.h:112
#define d
Definition: ke_i.h:81
#define debugstr_a
Definition: kernel32.h:31
#define FD_CLOEXEC
Definition: fcntl.h:102
Definition: tcpip.h:125
_CRTIMP intptr_t __cdecl execvp(_In_z_ const char *_Filename, _In_z_ char *const _ArgList[])
const GLubyte * c
Definition: glext.h:8905
#define SetLastError(x)
Definition: compat.h:417
unsigned char Ttl
Definition: ipexport.h:33
_Must_inspect_result_ _In_ PFLT_PORT _In_ ULONG _Out_writes_bytes_opt_ ReplyLength PVOID ReplyBuffer
Definition: fltkernel.h:1903
GLenum const GLvoid * addr
Definition: glext.h:9621
ULONG RoundTripTime
Definition: ipexport.h:71
#define memcpy(s1, s2, n)
Definition: mkisofs.h:878
#define close
Definition: acwin.h:98
#define ERR(fmt,...)
Definition: debug.h:109
static ULONG Timeout
Definition: ping.c:61
#define ERROR_NOT_SUPPORTED
Definition: compat.h:90
GLuint res
Definition: glext.h:9613
char * strcpy(char *DstString, const char *SrcString)
Definition: utclib.c:388
#define c
Definition: ke_i.h:80
struct ip_option_information Options
Definition: ipexport.h:75
GLboolean GLboolean GLboolean GLboolean a
Definition: glext.h:6204
_Must_inspect_result_ typedef _In_ PHYSICAL_ADDRESS _Out_ PPHYSICAL_ADDRESS DestinationAddress
Definition: iotypes.h:1090
#define memset(x, y, z)
Definition: compat.h:39
static SERVICE_STATUS status
Definition: service.c:31
_CRTIMP int __cdecl read(_In_ int _FileHandle, _Out_writes_bytes_(_MaxCharCount) void *_DstBuf, _In_ unsigned int _MaxCharCount)
#define ERROR_OUTOFMEMORY
Definition: deptool.c:13
unsigned int(__cdecl typeof(jpeg_read_scanlines))(struct jpeg_decompress_struct *
Definition: typeof.h:31
Definition: ps.c:97

Referenced by IcmpSendEcho().

◆ WINE_DECLARE_DEBUG_CHANNEL()

WINE_DECLARE_DEBUG_CHANNEL ( winediag  )

◆ WINE_DEFAULT_DEBUG_CHANNEL()

WINE_DEFAULT_DEBUG_CHANNEL ( icmp  )

Variable Documentation

◆ icmp_sequence

LONG icmp_sequence =0
static

Definition at line 130 of file icmp.c.

Referenced by IcmpSendEcho().