Leaked source code of windows server 2003
You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
|
|
/*****************************************************************************
* * $Workfile: PingICMP.cpp $ * * Copyright (C) 1997 Hewlett-Packard Company. * Copyright (C) 1997 Microsoft Corporation. * All rights reserved. * * 11311 Chinden Blvd. * Boise, Idaho 83714 * *****************************************************************************/
#include "precomp.h"
#include "pingicmp.h"
///////////////////////////////////////////////////////////////////////////////
// CPingICMP::CPingICMP()
CPingICMP::CPingICMP(const char *pHost) : hIcmp(INVALID_HANDLE_VALUE), m_iLastError(NO_ERROR) { strncpyn(m_szHost, pHost, sizeof( m_szHost)); } // ::CPingICMP()
///////////////////////////////////////////////////////////////////////////////
// CPingICMP::~CPingICMP()
CPingICMP::~CPingICMP() { _ASSERTE(hIcmp == INVALID_HANDLE_VALUE); } // ::~CPingICMP()
///////////////////////////////////////////////////////////////////////////////
// Open -- AF_INET, SOCK_RAW, IPPROTO_ICMP
BOOL CPingICMP::Open() { _ASSERTE(hIcmp == INVALID_HANDLE_VALUE);
if ( (hIcmp = IcmpCreateFile()) == INVALID_HANDLE_VALUE ) { m_iLastError = GetLastError(); return FALSE; }
return TRUE; } // ::Open()
///////////////////////////////////////////////////////////////////////////////
// Close
BOOL CPingICMP::Close() { BOOL bRet = (hIcmp == INVALID_HANDLE_VALUE || IcmpCloseHandle(hIcmp));
if ( !bRet ) m_iLastError = GetLastError(); else hIcmp = INVALID_HANDLE_VALUE;
return bRet;
} // ::Close()
///////////////////////////////////////////////////////////////////////////////
// Ping -- sends an ICMP Echo Request & reads the ICMP Echo Reply back. It
// records the round trip time.
// Note: SOCK_RAW support is optional in WinSock V1.1, so this will not
// work over all WinSock implementations.
// Error Codes:
// NO_ERROR if successfull
// WinSock error otherwise
BOOL CPingICMP::Ping() { BOOL bRet = FALSE; DWORD timeOut = 5 * 1000; // 5 seconds, 5000 milliseconds
int i, nReplies, nRetries = 2; // It is not necessary to retry 3 times.
// Printers need retry means they are
// too far away to print
char cSendBuf[4], cRcvBuf[1024]; IP_OPTION_INFORMATION IpOptions; PICMP_ECHO_REPLY pReply; IPAddr IpAddr;
if ( (IpAddr = ResolveAddress()) == INADDR_NONE || !Open() ) return FALSE;
ZeroMemory(&IpOptions, sizeof(IpOptions)); IpOptions.Ttl = 128; // From ping utility (net\sockets\tcpcmd\ping)
//
// *** Since 0 initialized the following is not needed
//
// IpOptions.Tos = 0;
// IpOptions.OptionsSize = 0;
// IpOptions.OptionsData = NULL;
// IpOptions.Flags = 0;
for ( i = 0 ; i < sizeof(cSendBuf) ; ++i ) cSendBuf[i] = 'a' + i;
// send ICMP echo request
for (i = 0; !bRet && i < nRetries; i++) {
nReplies = IcmpSendEcho(hIcmp, IpAddr, cSendBuf, sizeof(cSendBuf), &IpOptions, cRcvBuf, sizeof(cRcvBuf), timeOut);
pReply = (PICMP_ECHO_REPLY)cRcvBuf; while (!bRet && nReplies--) { bRet = sizeof(cSendBuf) == pReply->DataSize && memcmp(cSendBuf, pReply->Data, sizeof(cSendBuf)) == 0; pReply++; } }
Close();
return bRet; // device is found
} // ::Ping()
///////////////////////////////////////////////////////////////////////////////
// ResolveAddress
IPAddr CPingICMP::ResolveAddress() { IPAddr ipAddr = INADDR_NONE; struct hostent *h_info; /* host information */
/*
* m_szHost is not necessarily a host name. It could be an IP address as well */
if ( (ipAddr = inet_addr(m_szHost)) == INADDR_NONE ) { if ((h_info = gethostbyname(m_szHost)) != NULL) { /*
* Copy the IP address to the address structure. */ memcpy(&ipAddr, h_info->h_addr, sizeof(ipAddr)); } }
return ipAddr; }
|