天天看點

實作ping源代碼

//

// 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");

  // 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);

  // Init WinSock

  nRet = WSAStartup(0x0101, &wsaData );

        if (nRet)

        {

                fprintf(stderr,"\nWSAStartup() error: %d\n", nRet);    

                WSACleanup();

                return;

        }

        // Check WinSock version

        if (0x0101 != wsaData.wVersion)

                fprintf(stderr,"\nWinSock version 1.1 not supported\n");

  // 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]);

  // 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();

}

不好意思了,忘了哪下的...

繼續閱讀