WS_ICMP.C
上传用户:dansui
上传日期:2007-01-04
资源大小:71k
文件大小:23k
源码类别:

Ftp客户端

开发平台:

WINDOWS

  1. #include "ws_glob.h"
  2. #include "winftp.h"
  3. #include "winicmp.h"
  4. #include <stdio.h>
  5. #include <stdlib.h> 
  6. #include <direct.h>
  7. #include <dos.h>
  8. #include <stdarg.h>
  9. static char szPingHost[80];
  10. static HOSTENT HostEntry;
  11. static LPHOSTENT phe;
  12. static PROTOENT ProtoEntry;
  13. static LPPROTOENT ppe; 
  14. static HANDLE hTaskAsyncHost, hTaskAsyncProto;
  15. static HANDLE hStdCursor, hWaitCursor;
  16. static int nIndex, nRC, nBytesRecv;
  17. static int nTransmitted, nReceived;
  18. static int saFromAddrLen;
  19. static int nPktLength=50;
  20. static int nNumPkts=10;
  21. static u_long lTotalTime,lMinTime,lMaxTime;
  22. static bPingInProgress=FALSE;
  23. SOCKET sockPing=INVALID_SOCKET;
  24. int nMaxWait=5000;  // milliseconds
  25. int nExtent=0;
  26. int nExtra =0;
  27. //************************************************************************
  28. //  Add a line to the Ping List Box
  29. //************************************************************************
  30. void AddPingLine (HWND hDlg, LPSTR lpStr)
  31. {
  32.   HDC hDC;
  33.   HWND hWnd;
  34.   SIZE size;
  35.   
  36.   if (lpStr==NULL) return;
  37.   if (!bVerbose && lpStr[0]=='[') return;
  38.   SendDlgItemMessage (hDlg, IDD_LBPING, LB_ADDSTRING, (WPARAM) 0, (LPARAM)(LPCSTR) lpStr);
  39.   if (nExtra==0) nExtra = GetSystemMetrics (SM_CXVSCROLL);
  40.   hDC = GetDC (hWnd=GetDlgItem (hDlg, IDD_LBPING));
  41.   SelectObject (hDC, GetStockObject (ANSI_FIXED_FONT));
  42.   GetTextExtentPoint (hDC, lpStr, lstrlen (lpStr), &size);
  43.   ReleaseDC (hWnd, hDC);
  44.   if ((size.cx+nExtra)>nExtent) SendDlgItemMessage (hDlg, IDD_LBPING, LB_SETHORIZONTALEXTENT, (WPARAM) (nExtent=size.cx+2*nExtra), 0L);
  45. }
  46. //*************************************************************************
  47. //*************************************************************************
  48. void DoDlgPrintf (HWND hDlg, char *szFormat,...)
  49. {
  50.    va_list vaArgs;
  51.    static char szBuf[256];
  52.    va_start (vaArgs, szFormat);
  53.    if (vsprintf (szBuf, szFormat, vaArgs)!=EOF) AddPingLine (hDlg, szBuf);
  54.    va_end (vaArgs);
  55. }
  56. //*************************************************************************
  57. //*************************************************************************
  58. void PrintHeader (HWND hDlg, LPSOCKADDR_IN saDestAddr, int nDataSize)
  59. {
  60.   DoDlgPrintf (hDlg, "PING %s (%s): %u data bytes",
  61.       szPingHost, inet_ntoa (saDestAddr->sin_addr), nDataSize+SIZE_ICMP_HDR);
  62.   lMaxTime=lTotalTime=0l; 
  63.   lMinTime=99999999l;
  64. }
  65. //*************************************************************************
  66. //*************************************************************************
  67. void PrintStats (HWND hDlg) 
  68. {
  69.   AddPingLine (hDlg, " ");
  70.   DoDlgPrintf (hDlg, "PING Statistics for %s", szPingHost);
  71.   if (nTransmitted && nReceived)
  72.     DoDlgPrintf (hDlg, "%d packets transmitted, %d packets received, %d%% packet loss",
  73.         nTransmitted, nReceived, (int)(((nTransmitted-nReceived)*100)/nTransmitted));
  74.   else if (nTransmitted)
  75.     DoDlgPrintf (hDlg, "%d packets transmitted, %d packets received, 100%% packet loss",
  76.       nTransmitted, nReceived);
  77.   if (nReceived)
  78.     DoDlgPrintf (hDlg, "round-trip (ms) min/avg/max = %ld/%ld/%ld",
  79.          lMinTime, lTotalTime/nReceived, lMaxTime);
  80.   AddPingLine (hDlg, " ");
  81.   AddPingLine (hDlg, " ");
  82. }
  83. //************************************************************************
  84. // compute packet checksum
  85. //************************************************************************
  86. int in_cksum (u_short FAR *pPacket, int nBytes)
  87. {
  88.   long sum;
  89.   u_short oddbyte;
  90.   u_short answer;
  91.   sum=0l;
  92.   while(nBytes>1) { sum += *pPacket++; nBytes -= 2; }
  93.   if(nBytes==1) 
  94.   {
  95.     oddbyte=0;
  96.     *((u_char FAR *) &oddbyte) = *(u_char FAR *)pPacket;
  97.     sum += oddbyte;
  98.   }
  99.   sum = (sum >> 16) + (sum & 0xffff);
  100.   sum += (sum >> 16);
  101.   answer= (u_short) ~sum;
  102.   return (answer);
  103. }
  104. //************************************************************************
  105. //************************************************************************
  106. LPSTR ReturnICMPType (int nType)
  107. {
  108.   static char *ICMPTypeTable[]={
  109.     "Echo Reply", "ICMP 1", "ICMP 2", "DestUnrchbl",
  110.     "SrcQnch", "Redirect", "6", "7","Echo","9","10",
  111.     "Time Exceed", "ParamPrblm", "Timestamp", "Timestamp reply",
  112.     "InfoRqst", "InfoRply"
  113.   };
  114.   if(nType<0 || nType>16) return "Out-of-range";
  115.   return ICMPTypeTable[nType];
  116. }
  117. //************************************************************************
  118. //************************************************************************
  119. BOOL PrintPkt (HWND hDlg, LPSTR pPacket, int nLength, LPSOCKADDR_IN saFromAddr, BOOL bVerbose)
  120. {
  121.   int iphdrlen;
  122.   static struct ip *ip;
  123.   static struct icmp *icmp;
  124.   static struct in_addr *iptr;
  125.   u_long ulrc;
  126.   static u_long lEndTime,*lpStartTime,lTripTime;
  127.   lEndTime = GetTickCount();
  128.   saFromAddr->sin_addr.s_addr = ntohl (saFromAddr->sin_addr.s_addr);
  129.   ip = (struct ip *) pPacket;
  130.   iphdrlen = ip->ip_hl << 2;
  131.   if (nLength < iphdrlen + ICMP_MINLEN) 
  132.   {
  133.     if(bVerbose) 
  134.     {
  135.       ulrc=ntohl (saFromAddr->sin_addr.s_addr);
  136.       iptr = (struct in_addr *) &ulrc;
  137.       DoDlgPrintf (hDlg, "[received] too short (%d bytes) from %sn", nLength, inet_ntoa(*iptr));
  138.     }
  139.     return FALSE;
  140.   }
  141.   nLength -= iphdrlen;
  142.   icmp=(struct icmp *)(pPacket + iphdrlen);
  143.   if (icmp->icmp_type != ICMP_ECHOREPLY) 
  144.   {
  145.     if (bVerbose) 
  146.     {
  147.       ulrc=ntohl(saFromAddr->sin_addr.s_addr);
  148.       iptr = (struct in_addr *) &ulrc;
  149.       DoDlgPrintf (hDlg, "[received] %d bytes from %s: icmp_type=%d (%s) icmp_code=%d",
  150.         nLength, inet_ntoa(*iptr), icmp->icmp_type, ReturnICMPType(icmp->icmp_type), icmp->icmp_code);
  151.     }
  152.     return FALSE;
  153.   }
  154.   ulrc = ntohl (saFromAddr->sin_addr.s_addr);
  155.   iptr = (struct in_addr *) &ulrc;
  156.   if (icmp->icmp_id!=(WORD) hDlg) 
  157.   {
  158.     DoDlgPrintf (hDlg, "RCV %d bytes from %s. not for us", nLength, inet_ntoa (*iptr));
  159.     return FALSE;
  160.   }
  161.   lpStartTime = (u_long *) (pPacket + SIZE_ICMP_HDR);
  162.   lTripTime = lEndTime - *lpStartTime;
  163.   lTotalTime += lTripTime;
  164.   if(lTripTime < lMinTime) lMinTime=lTripTime;
  165.   if(lTripTime > lMaxTime) lMaxTime=lTripTime;
  166.   DoDlgPrintf (hDlg, "%-12s:(%3d) %6ldms %4d bytes",
  167.        inet_ntoa(*iptr), icmp->icmp_seq, lTripTime, nLength);
  168.   nReceived++;
  169.   return TRUE;
  170. }
  171. //************************************************************************
  172. //************************************************************************
  173. int send_ping (HWND hDlg, SOCKET sockfd, LPSOCKADDR_IN saDestAddr, LPSTR pPacket, int nLength)
  174. {
  175.   int nRC;
  176.   struct icmp *icmp;
  177.   u_long *timeloc;
  178.   nLength+=SIZE_ICMP_HDR;
  179.   icmp=(struct icmp *)pPacket;
  180.   // set the send time
  181.   timeloc= (u_long *) (pPacket+SIZE_ICMP_HDR);
  182.   *timeloc=GetTickCount();
  183.   // complete the ICMP packet header
  184.   icmp->icmp_type=ICMP_ECHO;
  185.   icmp->icmp_code=0;
  186.   icmp->icmp_cksum=0;
  187.   icmp->icmp_id = (int) hDlg;
  188.   icmp->icmp_seq=nTransmitted;
  189.   // compute the checksum
  190.   icmp->icmp_cksum = in_cksum ((u_short FAR *) icmp, nLength);
  191.   // send the packet
  192.   if ((nRC = sendto (sockfd, pPacket, nLength,0, (struct sockaddr *) saDestAddr,
  193.                  sizeof(struct sockaddr)))==SOCKET_ERROR) 
  194.   {
  195.     DoDlgPrintf(hDlg, "[sendto] %s", ReturnWSError (WSAGetLastError(), NULL));
  196.     if (WSAGetLastError()!=WSAEWOULDBLOCK && WSAGetLastError()!=WSAEINPROGRESS)
  197.       nTransmitted++;
  198.   } 
  199.   else 
  200.   {
  201.     nTransmitted++;
  202.     if (nRC!=nLength)
  203.       DoDlgPrintf (hDlg, "[sendto] wrote %d bytes, return=%d",nLength,nRC);
  204.   }
  205.   return (nRC==nLength);
  206. }
  207. //************************************************************************
  208. //************************************************************************
  209. recv_ping (HWND hDlg, SOCKET sockfd, LPSTR szRecvPkt, BOOL bPrintFlag)
  210. {
  211.   int  nBytesRecv;
  212.   int  saFromAddrLen;
  213.   struct sockaddr_in  saFromAddr;
  214.   int  nRC;
  215. // NOTE: this is for the blocking version..... this means we won't exit
  216. // until we get the packet(s) we are looking for.  This means we have to
  217. // use a timer function to make us exit.
  218.   nRC = FALSE;
  219.   saFromAddrLen = sizeof (saFromAddr);
  220.   SetTimer (hDlg, 10, nMaxWait, NULL);
  221.   nBytesRecv = recvfrom (sockfd, szRecvPkt, MAXPACKET,0, (struct sockaddr *)&saFromAddr, &saFromAddrLen);
  222.   KillTimer (hDlg, 10);
  223.   if (nBytesRecv!=SOCKET_ERROR || WSAGetLastError()!=WSAEINTR) 
  224.   {
  225.     if (nBytesRecv==SOCKET_ERROR) 
  226.     {
  227.       DoDlgPrintf (hDlg, "[recvfrom] %s",ReturnWSError(WSAGetLastError(),NULL));
  228.       return FALSE;
  229.     } 
  230.     else
  231.     {
  232.       nRC = PrintPkt (hDlg, szRecvPkt, nBytesRecv, &saFromAddr, bPrintFlag);
  233.     }
  234.   }
  235.   return nRC;
  236. }
  237. //************************************************************************
  238. //  Run Ping Async mode
  239. //************************************************************************
  240. BOOL DoAsyncPing (HWND hDlg)
  241. {
  242.   bPingInProgress = TRUE;
  243.   memset (&saDestAddr, 0, sizeof(struct sockaddr_in));
  244.   memset (&HostEntry,  0, sizeof(struct hostent));
  245.   memset (&ProtoEntry, 0, sizeof(struct protoent));
  246.   saDestAddr.sin_family=AF_INET;
  247.   if ((saDestAddr.sin_addr.s_addr=inet_addr (szPingHost))==INADDR_NONE)
  248.        hTaskAsyncHost = WSAAsyncGetHostByName (hDlg, WM_PING_HOST, szPingHost, szMsgBuf, MAXGETHOSTSTRUCT);
  249.   else hTaskAsyncHost = 0;
  250.   hTaskAsyncProto = WSAAsyncGetProtoByName (hDlg, WM_PING_PROTO, "icmp", szMsgBuf+MAXGETHOSTSTRUCT, MAXGETHOSTSTRUCT);
  251.   return TRUE;
  252. }
  253. //************************************************************************
  254. //  Run Ping Blocking mode
  255. //************************************************************************
  256. BOOL DoBlockingPing (HWND hDlg)
  257. {
  258.   int nProto;
  259.   
  260.   bPingInProgress = TRUE;
  261.   memset (&saDestAddr, 0, sizeof (struct sockaddr));
  262.   saDestAddr.sin_family = AF_INET;
  263.   if ((saDestAddr.sin_addr.s_addr=inet_addr (szPingHost))==INADDR_NONE)
  264.   {
  265.     if ((phe = gethostbyname (szPingHost))!=NULL)
  266.     {
  267.       memcpy (&saDestAddr.sin_addr, phe->h_addr, phe->h_length);
  268.     }
  269.     else
  270.     {
  271.       DoDlgPrintf (hDlg, "can't get "%s" host entry.", szPingHost);
  272.       SendMessage (hDlg, WM_RESETCURSOR, 0, 0l);
  273.       return TRUE;
  274.     }
  275.   }
  276.   if ((ppe=getprotobyname("icmp"))==NULL) 
  277.   {
  278.     DoDlgPrintf (hDlg, "[Proto] Unknown Protocol: icmp Using Default");
  279.     nProto = 1;
  280.   }
  281.   else
  282.   {
  283.     nProto = ppe->p_proto;
  284.   }
  285.   
  286.   if ((sockPing=socket (saDestAddr.sin_family, SOCK_RAW, nProto))==INVALID_SOCKET)
  287.   {
  288.     DoDlgPrintf (hDlg, "Can't Create Raw Socket %s", ReturnWSError (WSAGetLastError(), NULL));
  289.     SendMessage (hDlg, WM_RESETCURSOR, 0, 0l);
  290.     return TRUE;
  291.   }
  292.   SetWindowText (GetDlgItem (hDlg, IDD_PING), "Reset");
  293.   nTransmitted=0; nReceived=0;
  294.   PrintHeader (hDlg, &saDestAddr, nPktLength);
  295.   SetTimer (hDlg, 30, 1000, NULL);
  296.   return TRUE;
  297. }
  298. //************************************************************************
  299. //  Process the IDOK message - Resolve the Name
  300. //************************************************************************
  301. BOOL OnDlgCmdIdOk (HWND hDlg, WORD wCtlID, WORD wNotifyCode)
  302. {
  303.   int nCount = 0;
  304.   char szBuf[30];
  305.   
  306.   GetDlgItemText (hDlg, IDD_HOSTNAME, szPingHost, 79);
  307.   if ((phe = gethostbyname (szPingHost)) == NULL) 
  308.   {
  309.     MessageBox (hDlg, "GetHostByName() failed", "Error", MB_OK);
  310.     return TRUE;
  311.   }
  312.   nCount = 0;
  313.   SendDlgItemMessage (hDlg, IDD_LBALIAS, LB_RESETCONTENT, (WPARAM) 0, (LPARAM) 0);
  314.   SendDlgItemMessage (hDlg, IDD_LBADDR,  LB_RESETCONTENT, (WPARAM) 0, (LPARAM) 0);
  315.   SendDlgItemMessage (hDlg, IDD_LBPING,  LB_RESETCONTENT, (WPARAM) 0, (LPARAM) 0);
  316.   SendDlgItemMessage (hDlg, IDD_LBALIAS, LB_ADDSTRING, 0, (LPARAM) (phe->h_name));
  317.   while (phe->h_aliases[nCount] != NULL) 
  318.   {
  319.     SendDlgItemMessage (hDlg, IDD_LBALIAS, LB_ADDSTRING, 0, (LPARAM) (phe->h_aliases[nCount]));
  320.     nCount++;
  321.   }
  322.   nCount = 0;
  323.   while (phe->h_addr_list[nCount] != NULL) 
  324.   {
  325.     sprintf (szBuf, "%u.%u.%u.%u", (unsigned char) phe->h_addr_list[nCount][0],
  326.        (unsigned char) phe->h_addr_list[nCount][1],
  327.        (unsigned char) phe->h_addr_list[nCount][2],
  328.        (unsigned char) phe->h_addr_list[nCount][3]);
  329.     nCount++;
  330.     if (SendDlgItemMessage (hDlg, IDD_LBADDR, LB_ADDSTRING, 0, (LPARAM)(LPCSTR) szBuf) == LB_ERR)
  331.        MessageBox (hDlg, szBuf, "Couldn't add address..", MB_OK);
  332.   }
  333.   return TRUE;
  334. }
  335. //***********************************************************************
  336. //  Process the IDD_PING command
  337. //***********************************************************************
  338. BOOL OnDlgCmdPingHost (HWND hDlg, WORD wCtlID, WORD wNotifyCode)
  339. {
  340.   if (bPingInProgress) 
  341.   {
  342.     if (sockPing!=INVALID_SOCKET) 
  343.     {
  344.       KillTimer (hDlg, 10);
  345.       KillTimer (hDlg, 20);
  346.       KillTimer (hDlg, 30);
  347.       if (WSAIsBlocking()) WSACancelBlockingCall();
  348.       sockPing = DoClose (sockPing);
  349.       SendMessage(hDlg, WM_RESETCURSOR, 0, 0l);
  350.       SetWindowText (GetDlgItem (hDlg, IDD_PING), "Ping Host");
  351.     }
  352.     bPingInProgress = FALSE; 
  353.     return TRUE;
  354.   }
  355.   if (GetDlgItemText (hDlg, IDD_HOSTNAME, szPingHost, 79)==0) return 0;
  356.   nNumPkts   = GetDlgItemInt (hDlg, IDD_PINGCOUNT, NULL, FALSE);
  357.   nNumPkts = __max (nNumPkts, 1);
  358.   nPktLength = GetDlgItemInt (hDlg, IDD_PKTSIZE, NULL, FALSE);
  359.   nPktLength = __min (__max (nPktLength, sizeof (struct icmp)), MAXPACKET);
  360.   switch ((int) IsDlgButtonChecked (hDlg, IDC_BLOCKINGPING))
  361.   {
  362.     case  0  : DoAsyncPing (hDlg); break;
  363.     default  : DoBlockingPing (hDlg); break;
  364.   }
  365.   return TRUE;
  366. }
  367. //***********************************************************************
  368. //  Process the Cancel Button
  369. //***********************************************************************
  370. BOOL OnDlgCmdCancel (HWND hDlg, WORD wCtlID, WORD wNotifyCode)
  371. {
  372.   if (sockPing!=INVALID_SOCKET) 
  373.   {
  374.     sockPing = DoClose (sockPing);
  375.     SendMessage(hDlg, WM_RESETCURSOR, 0, 0l);
  376.   }
  377.   EndDialog (hDlg, FALSE); 
  378.   return TRUE;
  379. }
  380. //***********************************************************************
  381. //  Process the WM_COMMAND message
  382. //***********************************************************************
  383. BOOL OnDlgCommand (HWND hDlg, UINT Msg, WPARAM wParam, LPARAM lParam)
  384. {
  385.   int count = 0;
  386.   WORD wNotifyCode;
  387.   WORD wCtlID;
  388. #ifdef WIN32
  389.   wNotifyCode = HIWORD (wParam);
  390.   wCtlID      = LOWORD (wParam);
  391. #else
  392.   wNotifyCode = HIWORD (lParam);
  393.   wCtlID      = wParam;
  394. #endif
  395.   
  396.   switch (wCtlID)
  397.   {
  398.     case IDOK     : OnDlgCmdIdOk (hDlg, wCtlID, wNotifyCode); return TRUE;
  399.     case IDD_PING : OnDlgCmdPingHost (hDlg, wCtlID, wNotifyCode); return TRUE;
  400.     case IDCANCEL : OnDlgCmdCancel (hDlg, wCtlID, wNotifyCode); return TRUE;
  401.     default       : return FALSE;
  402.   }
  403.   return TRUE;
  404. }
  405. //***********************************************************************
  406. //  Process the WM_TIMER message
  407. //***********************************************************************
  408. BOOL OnDlgTimer (HWND hDlg, UINT Msg, WPARAM wParam, LPARAM lParam)
  409. {
  410.   switch (wParam) 
  411.   {
  412.     case 10: AddPingLine (hDlg, "[Timer-TIMEOUT] ");
  413.              KillTimer (hDlg, 10);
  414.              if (WSAIsBlocking()) WSACancelBlockingCall();
  415.              bPingInProgress = FALSE;
  416.              break;
  417.     case 20: if (nTransmitted<nNumPkts) 
  418.              {
  419.                send_ping (hDlg, sockPing, &saDestAddr, szMsgBuf, nPktLength+SIZE_ICMP_HDR);
  420.                PostMessage(hDlg, WM_PING_RECEIVE, 0, 0l);
  421.              } 
  422.              else 
  423.              {
  424.                KillTimer (hDlg, 20);
  425.                if (nReceived!=nTransmitted) SendMessage (hDlg, WM_PING_RECEIVE, 0, 0l);
  426.                PostMessage (hDlg, WM_PING_FINISH, 0, 0l);
  427.              }
  428.              break;
  429.     case 30: if (nTransmitted<nNumPkts)
  430.              {
  431.                if (send_ping (hDlg, sockPing, &saDestAddr, szMsgBuf, nPktLength+SIZE_ICMP_HDR))
  432.                   recv_ping (hDlg, sockPing, szString, TRUE);
  433.              }
  434.              else 
  435.              {
  436.                KillTimer (hDlg, 30);
  437.                if (nReceived!=nTransmitted) recv_ping (hDlg, sockPing, szString, TRUE);
  438.                PostMessage (hDlg, WM_PING_FINISH, 0, 0l);
  439.              }
  440.              break;
  441.     default: KillTimer (hDlg, wParam);
  442.              break;
  443.   }
  444.   return TRUE;
  445. }
  446. //***********************************************************************
  447. //***********************************************************************
  448. BOOL OnDlgPingHost (HWND hDlg, UINT Msg, WPARAM wParam, LPARAM lParam)
  449. {
  450.   if (WSAGETASYNCERROR (lParam)!=0) 
  451.   {
  452.     ReportWSError (NULL, WSAGETASYNCERROR (lParam));
  453.     SendMessage (hDlg, WM_RESETCURSOR, 0, 0l);
  454.   } 
  455.   else 
  456.   {
  457.     memcpy (&HostEntry, szMsgBuf, sizeof (struct hostent));
  458.     memcpy (&saDestAddr.sin_addr, HostEntry.h_addr, HostEntry.h_length);
  459.     hTaskAsyncHost=0;
  460.     if (hTaskAsyncProto==0) PostMessage (hDlg, WM_PING_CAS, 0, 0l);
  461.   }
  462.   return TRUE;
  463. }
  464. //***********************************************************************
  465. //***********************************************************************
  466. BOOL OnDlgPingProto (HWND hDlg, UINT Msg, WPARAM wParam, LPARAM lParam)
  467. {
  468.   if (WSAGETASYNCERROR (lParam)!=0) 
  469.   {
  470.     ReportWSError (NULL, WSAGETASYNCERROR (lParam));
  471.     SendMessage (hDlg, WM_RESETCURSOR, 0, 0l);
  472.   } 
  473.   else 
  474.   {
  475.     memcpy (&ProtoEntry, szMsgBuf+MAXGETHOSTSTRUCT, sizeof (struct protoent));
  476.     hTaskAsyncProto=0;
  477.     if (hTaskAsyncHost==0) PostMessage (hDlg, WM_PING_CAS, 0, 0l);
  478.   }
  479.   return 0;
  480. }
  481. //***********************************************************************
  482. //***********************************************************************
  483. BOOL OnDlgPingAsync (HWND hDlg, UINT Msg, WPARAM wParam, LPARAM lParam)
  484. {
  485.   PrintHeader (hDlg, &saDestAddr, nPktLength+SIZE_ICMP_HDR);
  486.   sockPing = socket (saDestAddr.sin_family, SOCK_RAW, ProtoEntry.p_proto);
  487.   if (sockPing==INVALID_SOCKET) 
  488.   {
  489.     DoDlgPrintf (hDlg, "Can't Create Raw Socket: %s", ReturnWSError (WSAGetLastError(), NULL));
  490.     SendMessage (hDlg, WM_RESETCURSOR, 0, 0l);
  491.   } 
  492.   else 
  493.   {
  494.     if (WSAAsyncSelect (sockPing, hDlg, WM_PING_RECEIVE, FD_READ)==SOCKET_ERROR)
  495.     {
  496.       DoDlgPrintf (hDlg, "AsyncSelect: %s", ReturnWSError (WSAGetLastError(), NULL));
  497.       sockPing = DoClose (sockPing);
  498.       SendMessage (hDlg, WM_RESETCURSOR, 0, 0l);
  499.     } 
  500.     else 
  501.     {
  502.       SetWindowText (GetDlgItem (hDlg, IDD_PING), "Reset");
  503.       nTransmitted = nReceived = 0;
  504.       SetTimer (hDlg, 20, 1000, NULL);
  505.     }
  506.   }
  507.   return TRUE;
  508. }
  509. //***********************************************************************
  510. //***********************************************************************
  511. BOOL OnDlgPingRecv (HWND hDlg, UINT Msg, WPARAM wParam, LPARAM lParam)
  512. {
  513.   saFromAddrLen = sizeof(struct sockaddr);
  514.   nBytesRecv = recvfrom (sockPing, szString, MAXPACKET, 0, (struct sockaddr *)&saFromAddr, &saFromAddrLen);
  515.   if (nBytesRecv==SOCKET_ERROR) 
  516.   {
  517.     DoDlgPrintf (hDlg, "[Recv] %s", ReturnWSError (WSAGetLastError(), NULL));
  518.   } 
  519.   else
  520.   {
  521.     PrintPkt (hDlg, szString, nBytesRecv, &saFromAddr, TRUE);
  522.   }
  523.   return TRUE;
  524. }
  525. //***********************************************************************
  526. //***********************************************************************
  527. BOOL OnDlgPingFinish (HWND hDlg, UINT Msg, WPARAM wParam, LPARAM lParam)
  528. {
  529.   sockPing = DoClose (sockPing);
  530.   KillTimer (hDlg, 10);
  531.   PrintStats (hDlg);
  532.   bPingInProgress = FALSE;
  533.   SetWindowText (GetDlgItem (hDlg, IDD_PING), "Ping Host");
  534.   return TRUE;
  535. }
  536. //***********************************************************************
  537. //***********************************************************************
  538. BOOL OnDlgResetCursor (hDlg, Msg, wParam, lParam)
  539. {
  540.   bCmdInProgress=FALSE;
  541.   SetCursor(hStdCursor);
  542.   return TRUE;
  543. }
  544. //***********************************************************************
  545. //***********************************************************************
  546. BOOL OnDlgSetCursor (hDlg, Msg, wParam, lParam)
  547. {
  548.   if (bCmdInProgress) 
  549.   {
  550.     SetCursor (hWaitCursor);
  551.     return TRUE;
  552.   }
  553.   return FALSE;
  554. }
  555. //***********************************************************************
  556. //***********************************************************************
  557. BOOL OnDlgInitDlg (HWND hDlg, UINT Msg, WPARAM wParam, LPARAM lParam)
  558. {
  559.   SetDlgItemText (hDlg, IDD_HOSTNAME, szRemoteHost);
  560.   SetDlgItemInt (hDlg, IDD_PINGCOUNT, nNumPkts, FALSE);
  561.   SetDlgItemInt (hDlg, IDD_PKTSIZE, nPktLength, FALSE);
  562.   CheckRadioButton (hDlg, IDC_ASYNCPING, IDC_BLOCKINGPING, IDC_ASYNCPING);
  563.   SendDlgItemMessage (hDlg, IDD_LBPING, WM_SETFONT, (WPARAM) GetStockObject (ANSI_FIXED_FONT), (LPARAM) 0);
  564.   sockPing = INVALID_SOCKET;
  565.   return TRUE;
  566. }
  567. //***********************************************************************
  568. //***********************************************************************
  569. BOOL OnDlgResize (HWND hDlg, UINT Msg, WPARAM wParam, LPARAM lParam)
  570. {
  571.   int cx=LOWORD (lParam);
  572.   int cy=HIWORD (lParam);
  573.   DWORD dwBase;
  574.   int cxb, cyb;
  575.   int cTmpX, cTmpY;
  576.   
  577.   dwBase = GetDialogBaseUnits();
  578.   cxb = LOWORD (dwBase) / 4;
  579.   cyb = HIWORD (dwBase) / 8;
  580.   if (cxb==0 || cyb==0) return 0;
  581.   cx /= cxb;
  582.   cy /= cyb;
  583.   if (cx<145) return 0;
  584.   if (cy<190) return 0;
  585.   cTmpX = (cx-15)/3;
  586.   cTmpY = cy - 120 - 20;
  587.   MoveWindow (GetDlgItem (hDlg, IDC_BOX_BLOCK), 92*cxb,      0, (cx-92-3)*cxb, 36*cyb, TRUE);
  588.   MoveWindow (GetDlgItem (hDlg, IDC_BOX_HOST) ,  2*cxb, 34*cyb, (cx- 2-3)*cxb, 25*cyb, TRUE);
  589.   MoveWindow (GetDlgItem (hDlg, IDD_HOSTNAME) , 28*cxb, 41*cyb, (cx-28-7)*cxb, 15*cyb, TRUE);
  590.   MoveWindow (GetDlgItem (hDlg, IDC_BOX_ALIAS),  2*cxb, 59*cyb, (cx- 2-3)*cxb, 59*cyb, TRUE);
  591.   MoveWindow (GetDlgItem (hDlg, IDD_LBALIAS)  ,  6*cxb, 70*cyb, (cx- 6-7)*cxb, 21*cxb, TRUE);
  592.   MoveWindow (GetDlgItem (hDlg, IDD_LBADDR)   ,  6*cxb, 93*cyb, (cx- 6-7)*cxb, 21*cyb, TRUE);
  593.   MoveWindow (GetDlgItem (hDlg, IDD_LBPING)   ,  2*cxb,120*cyb, (cx- 2-3)*cxb, cTmpY*cyb, TRUE);
  594.   
  595.   cTmpY += 122;
  596.   
  597.   MoveWindow (GetDlgItem (hDlg, IDOK)    ,           2*cxb, cTmpY*cyb, (cTmpX-2)*cxb, 15*cyb, TRUE);
  598.   MoveWindow (GetDlgItem (hDlg, IDD_PING),   (cTmpX+2)*cxb, cTmpY*cyb, (cTmpX-2)*cxb, 15*cyb, TRUE);
  599.   MoveWindow (GetDlgItem (hDlg, IDCANCEL), (2*cTmpX+4)*cxb, cTmpY*cyb, (cTmpX-2)*cxb, 15*cyb, TRUE);
  600.   SendDlgItemMessage (hDlg, IDD_LBPING, LB_SETHORIZONTALEXTENT, (WPARAM) nExtent, 0L);
  601.   return TRUE;
  602. }
  603. //***********************************************************************
  604. // Misc Dialog Window Procedures                                        *
  605. //***********************************************************************
  606. BOOL CALLBACK WS_FindHostProc (HWND hDlg, UINT Msg, WPARAM wParam, LPARAM lParam)
  607.   switch (Msg)
  608.   {
  609.    case WM_INITDIALOG  : return OnDlgInitDlg (hDlg, Msg, wParam, lParam);
  610.    case WM_SIZE        : return OnDlgResize (hDlg, Msg, wParam, lParam);
  611.     case WM_TIMER       : return OnDlgTimer (hDlg, Msg, wParam, lParam);
  612.    case WM_COMMAND     : return OnDlgCommand (hDlg, Msg, wParam, lParam);
  613.     case WM_PING_HOST   : return OnDlgPingHost (hDlg, Msg, wParam, lParam);
  614.     case WM_PING_PROTO  : return OnDlgPingProto (hDlg, Msg, wParam, lParam);
  615.     case WM_PING_CAS    : return OnDlgPingAsync (hDlg, Msg, wParam, lParam);
  616.     case WM_PING_RECEIVE: return OnDlgPingRecv (hDlg, Msg, wParam, lParam);
  617.     case WM_PING_FINISH : return OnDlgPingFinish (hDlg, Msg, wParam, lParam);
  618.     case WM_RESETCURSOR : return OnDlgResetCursor (hDlg, Msg, wParam, lParam);
  619.     case WM_SETCURSOR   : return OnDlgSetCursor (hDlg, Msg, wParam, lParam);
  620.     default             : return FALSE;
  621.   }
  622.   return FALSE;
  623. }