一个Ping的实现源码

来源:互联网 发布:数据挖掘与分析 pdf 编辑:程序博客网 时间:2024/06/16 23:49
//
// PingI.c -- Simple ping program using the proprietary
//          Microsoft ICMP API
//
 
#include <windows.h>
#include <winsock.h>
#include <stdio.h>
#include <string.h>

typedef struct tagIPINFO
{
   u_char Ttl;            // Time To Live
   u_char Tos;            // Type Of Service
   u_char IPFlags;         // IP flags
   u_char OptSize;         // Size of options data
   u_char FAR *Options;   // Options data buffer
}IPINFO, *PIPINFO;

typedef struct tagICMPECHO
{
   u_long Source;         // Source address
   u_long Status;         // IP status
   u_long RTTime;         // Round trip time in milliseconds
   u_short DataSize;      // Reply data size
   u_short Reserved;      // Unknown
   void FAR *pData;      // Reply data buffer
   IPINFO   ipInfo;         // Reply options
}ICMPECHO, *PICMPECHO;


// ICMP.DLL Export Function Pointers
HANDLE (WINAPI *pIcmpCreateFile)(VOID);
BOOL (WINAPI *pIcmpCloseHandle)(HANDLE);
DWORD (WINAPI *pIcmpSendEcho)
   (HANDLE,DWORD,LPVOID,WORD,PIPINFO,LPVOID,DWORD,DWORD);

//
//
void main(int argc, char **argv)
{
   WSADATA wsaData;         // WSADATA
   ICMPECHO icmpEcho;         // ICMP Echo reply buffer
   HANDLE hndlIcmp;         // LoadLibrary() handle to ICMP.DLL
   HANDLE hndlFile;         // Handle for IcmpCreateFile()
    LPHOSTENT pHost;         // Pointer to host entry structure
    struct in_addr iaDest;      // Internet address structure
   DWORD *dwAddress;         // IP Address
   IPINFO ipInfo;            // IP Options structure
   int nRet;               // General use return code
   DWORD dwRet;            // DWORD return code
   int x;

   // Check arguments
   if (argc != 2)
   {
      fprintf(stderr,"/nSyntax: pingi HostNameOrIPAddress/n");
      return;
   }

   // Dynamically load the ICMP.DLL
   hndlIcmp = LoadLibrary("ICMP.DLL");
   if (hndlIcmp == NULL)
   {
      fprintf(stderr,"/nCould not load ICMP.DLL/n");
      return;
   }
   // Retrieve ICMP function pointers
   pIcmpCreateFile = (HANDLE (WINAPI *)(void))
      GetProcAddress(hndlIcmp,"IcmpCreateFile");
   pIcmpCloseHandle = (BOOL (WINAPI *)(HANDLE))
      GetProcAddress(hndlIcmp,"IcmpCloseHandle");
   pIcmpSendEcho = (DWORD (WINAPI *)
      (HANDLE,DWORD,LPVOID,WORD,PIPINFO,LPVOID,DWORD,DWORD))
      GetProcAddress(hndlIcmp,"IcmpSendEcho");
   // Check all the function pointers
   if (pIcmpCreateFile == NULL      ||
      pIcmpCloseHandle == NULL   ||
      pIcmpSendEcho == NULL)
   {
      fprintf(stderr,"/nError getting ICMP proc address/n");
      FreeLibrary(hndlIcmp);
      return;
   }

   // Init WinSock
   nRet = WSAStartup(0x0101, &wsaData );
    if (nRet)
    {
        fprintf(stderr,"/nWSAStartup() error: %d/n", nRet);
        WSACleanup();
      FreeLibrary(hndlIcmp);
        return;
    }
    // Check WinSock version
    if (0x0101 != wsaData.wVersion)
    {
        fprintf(stderr,"/nWinSock version 1.1 not supported/n");
        WSACleanup();
      FreeLibrary(hndlIcmp);
        return;
    }

   // Lookup destination
    // Use inet_addr() to determine if we're dealing with a name
    // or an address
    iaDest.s_addr = inet_addr(argv[1]);
    if (iaDest.s_addr == INADDR_NONE)
        pHost = gethostbyname(argv[1]);
    else
        pHost = gethostbyaddr((const char *)&iaDest,
                        sizeof(struct in_addr), AF_INET);
   if (pHost == NULL)
   {
      fprintf(stderr, "/n%s not found/n", argv[1]);
        WSACleanup();
      FreeLibrary(hndlIcmp);
      return;
   }

   // Tell the user what we're doing
   printf("/nPinging %s [%s]", pHost->h_name,
         inet_ntoa((*(LPIN_ADDR)pHost->h_addr_list[0])));

   // Copy the IP address
   dwAddress = (DWORD *)(*pHost->h_addr_list);

   // Get an ICMP echo request handle       
   hndlFile = pIcmpCreateFile();
   for (x = 0; x < 4; x++)
   {
      // Set some reasonable default values
      ipInfo.Ttl = 255;
      ipInfo.Tos = 0;
      ipInfo.IPFlags = 0;
      ipInfo.OptSize = 0;
      ipInfo.Options = NULL;
      //icmpEcho.ipInfo.Ttl = 256;
      // Reqest an ICMP echo
      dwRet = pIcmpSendEcho(
         hndlFile,      // Handle from IcmpCreateFile()
         *dwAddress,      // Destination IP address
         NULL,         // Pointer to buffer to send
         0,            // Size of buffer in bytes
         &ipInfo,      // Request options
         &icmpEcho,      // Reply buffer
         sizeof(struct tagICMPECHO),
         5000);         // Time to wait in milliseconds
      // Print the results
      iaDest.s_addr = icmpEcho.Source;
      printf("/nReply from %s  Time=%ldms  TTL=%d",
            inet_ntoa(iaDest),
            icmpEcho.RTTime,
            icmpEcho.ipInfo.Ttl);
      if (icmpEcho.Status)
      {
         printf("/nError: icmpEcho.Status=%ld",
            icmpEcho.Status);
         break;
      }
   }
   printf("/n");
   // Close the echo request file handle
   pIcmpCloseHandle(hndlFile);
   FreeLibrary(hndlIcmp);
   WSACleanup();
}
原创粉丝点击