|
|
/*++
Copyright (c) 1991 Microsoft Corporation
Module Name:
ping.c
Abstract:
Packet INternet Groper utility for TCP/IP.
Author:
Numerous TCP/IP folks.
Revision History:
Who When What -------- -------- ---------------------------------------------- WeihaiC 5-Dec-98. Moved from \nt\private\net\sockets\tcpcmd\ping MohsinA, 21-Oct-96. INADDR_NONE check to avoid broadcast. MohsinA, 13-Nov-96. Max packet size < 64K.
Notes:
--*/
//:ts=4
typedef unsigned long ULONG; typedef unsigned short ushort; typedef unsigned int UINT; typedef unsigned char UCHAR;
#include "precomp.h"
#include "icmpapi.h"
#define NOGDI
#define NOMINMAX
#define MAX_BUFFER_SIZE (sizeof(ICMP_ECHO_REPLY) + 0xfff7 + MAX_OPT_SIZE)
#define DEFAULT_BUFFER_SIZE (0x2000 - 8)
#define DEFAULT_SEND_SIZE 32
#define DEFAULT_COUNT 4
#define DEFAULT_TTL 32
#define DEFAULT_TOS 0
#define DEFAULT_TIMEOUT 5000L
#define MIN_INTERVAL 1000L
#define TRUE 1
#define FALSE 0
#define STDOUT 1
#define net_long(x) (((((ULONG)(x))&0xffL)<<24) | \
((((ULONG)(x))&0xff00L)<<8) | \ ((((ULONG)(x))&0xff0000L)>>8) | \ ((((ULONG)(x))&0xff000000L)>>24))
WSADATA WsaData;
// ========================================================================
// Caveat: return 0 for invalid, else internet address.
// I would prefer -1 for error. - MohsinA, 21-Nov-96.
unsigned long get_pingee(char *ahstr, char **hstr, int *was_inaddr, int dnsreq) { struct hostent *hostp = NULL; long inaddr;
if( strcmp( ahstr, "255.255.255.255" ) == 0 ){ return 0L; }
if ((inaddr = inet_addr(ahstr)) == -1L) { hostp = gethostbyname(ahstr); if (hostp) { /*
* If we find a host entry, set up the internet address */ inaddr = *(long *)hostp->h_addr; *was_inaddr = 0; } else { // Neither dotted, not name.
return(0L); }
} else { // Is dotted.
*was_inaddr = 1; if (dnsreq == 1) { hostp = gethostbyaddr((char *)&inaddr,sizeof(inaddr),AF_INET); } }
*hstr = hostp ? hostp->h_name : (char *)NULL; return(inaddr); }
// ========================================================================
BOOL Ping (LPTSTR pszServerName) { UINT i; int found_addr = 0; int dnsreq = 0; char *hostname = NULL; int was_inaddr; DWORD numberOfReplies; UINT Count = DEFAULT_COUNT; UCHAR TTL = DEFAULT_TTL; UCHAR FAR *Opt = (UCHAR FAR *)0; // Pointer to send options
UINT OptLength = 0; int OptIndex = 0; // Current index into SendOptions
int SRIndex = -1; // Where to put address, if source routing
UCHAR TOS = DEFAULT_TOS; UCHAR Flags = 0; ULONG Timeout = DEFAULT_TIMEOUT; IP_OPTION_INFORMATION SendOpts; int EndOffset; DWORD errorCode; HANDLE IcmpHandle = NULL; struct in_addr addr; PICMP_ECHO_REPLY reply; BOOL sourceRouting = FALSE; char *SendBuffer = NULL; char *RcvBuffer = NULL; UINT RcvSize; UINT SendSize = DEFAULT_SEND_SIZE; BOOL bRet = FALSE; IPAddr address = 0; // was local to main earlier.
char *arg;
// ====================================================================
#ifdef UNICODE
LPSTR pszAnsiServerName = NULL; DWORD uSize;
if (pszServerName && (uSize = WideCharToMultiByte(CP_ACP, 0, pszServerName, -1, NULL, 0, NULL, NULL))) {
if (pszAnsiServerName = (LPSTR) LocalAlloc(LPTR, uSize)) { if (!WideCharToMultiByte (CP_ACP, 0, pszServerName, -1, pszAnsiServerName, uSize, NULL, NULL))
goto CleanUp;
} else goto CleanUp;
}
arg = pszAnsiServerName;
#else
arg = pszServerName; #endif
if (WSAStartup( 0x0101, &WsaData)) goto CleanUp;
// Added check for INADDR_NONE, MohsinA, 21-Oct-96.
address = get_pingee(arg, &hostname, &was_inaddr, dnsreq); if(!address || (address == INADDR_NONE) ){ SetLastError (DNS_ERROR_INVALID_IP_ADDRESS); goto CleanUp; }
IcmpHandle = IcmpCreateFile();
if (IcmpHandle == INVALID_HANDLE_VALUE) { goto CleanUp; }
if (! (SendBuffer = (char *) LocalAlloc(LMEM_FIXED, SendSize))) { goto CleanUp; }
//
// Calculate receive buffer size and try to allocate it.
//
if (SendSize <= DEFAULT_SEND_SIZE) { RcvSize = DEFAULT_BUFFER_SIZE; } else { RcvSize = MAX_BUFFER_SIZE; }
if (! (RcvBuffer = (char *)LocalAlloc(LMEM_FIXED, RcvSize))) { goto CleanUp; }
//
// Initialize the send buffer pattern.
//
for (i = 0; i < SendSize; i++) { SendBuffer[i] = 'a' + (i % 23); }
//
// Initialize the send options
//
SendOpts.OptionsData = Opt; SendOpts.OptionsSize = (UCHAR)OptLength; SendOpts.Ttl = TTL; SendOpts.Tos = TOS; SendOpts.Flags = Flags;
addr.s_addr = address;
numberOfReplies = IcmpSendEcho(IcmpHandle, address, SendBuffer, (unsigned short) SendSize, &SendOpts, RcvBuffer, RcvSize, Timeout);
if (numberOfReplies == 0) {
errorCode = GetLastError();
goto CleanUp; } else {
reply = (PICMP_ECHO_REPLY) RcvBuffer;
while (numberOfReplies--) {
if (reply->Status == IP_SUCCESS) {
bRet = TRUE; break; }
reply++; } }
CleanUp:
#ifdef UNICODE
if (pszAnsiServerName) { LocalFree(pszAnsiServerName); } #endif
if (IcmpHandle) { IcmpCloseHandle(IcmpHandle); }
if (SendBuffer) { LocalFree(SendBuffer); }
if (RcvBuffer) { LocalFree(RcvBuffer); }
return bRet; }
|