icmp.cxx

来自「pwlib源码库」· CXX 代码 · 共 366 行

CXX
366
字号
/* * icmp.cxx * * ICMP class implementation for Win32. * * Portable Windows Library * * Copyright (c) 1993-1998 Equivalence Pty. Ltd. * * The contents of this file are subject to the Mozilla Public License * Version 1.0 (the "License"); you may not use this file except in * compliance with the License. You may obtain a copy of the License at * http://www.mozilla.org/MPL/ * * Software distributed under the License is distributed on an "AS IS" * basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See * the License for the specific language governing rights and limitations * under the License. * * The Original Code is Portable Windows Library. * * The Initial Developer of the Original Code is Equivalence Pty. Ltd. * * Portions are Copyright (C) 1993 Free Software Foundation, Inc. * All Rights Reserved. * * Contributor(s): ______________________________________. * * $Log: icmp.cxx,v $ * Revision 1.15  2004/02/15 02:53:32  rjongbloed * Added compatibility with Windows Mobile 2003, thanks Joerg Schoemer * * Revision 1.14  2001/09/10 02:51:23  robertj * Major change to fix problem with error codes being corrupted in a *   PChannel when have simultaneous reads and writes in threads. * * Revision 1.13  1999/08/08 09:29:37  robertj * Changed Success to PingSuccess to avoid namespace collision with X define of the same name * * Revision 1.12  1999/02/16 08:08:06  robertj * MSVC 6.0 compatibility changes. * * Revision 1.11  1998/11/30 04:48:39  robertj * New directory structure * * Revision 1.10  1998/09/24 03:30:46  robertj * Added open software license. * * Revision 1.9  1998/01/26 00:53:33  robertj * Added error codes, TTL and data buffer to Ping. * * Revision 1.8  1997/10/03 13:32:46  robertj * Changed to late binding so do not need icmp.lib to compile system. * * Revision 1.7  1996/10/29 13:27:17  robertj * Change ICMP to use DLL rather than Winsock * */#include <ptlib.h>#include <ptlib/sockets.h>#ifdef _WIN32_WCE#include "Icmpapi.h"typedef ICMP_ECHO_REPLY         ICMPECHO;typedef ip_option_information   IPINFO;#define RTTime RoundTripTimeclass PICMPDLL : public PObject{  PCLASSINFO(PICMPDLL, PObject);public:  HANDLE IcmpCreateFile() {    return ::IcmpCreateFile();  }  BOOL IcmpCloseHandle(HANDLE handle) {    return ::IcmpCloseHandle(handle);  }  DWORD IcmpSendEcho(    HANDLE   handle,           /* handle returned from IcmpCreateFile() */    u_long   destAddr,         /* destination IP address (in network order)/    void   * sendBuffer,       /* pointer to buffer to send */    WORD     sendLength,       /* length of data in buffer */    IPINFO * requestOptions,   /* see structure definition above */    void   * replyBuffer,      /* structure definitionm above */    DWORD    replySize,        /* size of reply buffer */    DWORD    timeout           /* time in milliseconds to wait for reply */    ) {    return ::IcmpSendEcho(      handle,      destAddr,      sendBuffer,      sendLength,      requestOptions,      replyBuffer,      replySize,      timeout);  }  bool IsLoaded() {    return true;  }} ICMP;#else // _WIN32_WCE/////////////////////////////////////////////////////////////////// Definitions for Microsft ICMP library//// return values from IcmpSendEcho#define IP_STATUS_BASE				11000#define IP_SUCCESS					0#define IP_BUF_TOO_SMALL			(IP_STATUS_BASE + 1)#define IP_DEST_NET_UNREACHABLE		(IP_STATUS_BASE + 2)#define IP_DEST_HOST_UNREACHABLE	(IP_STATUS_BASE + 3)#define IP_DEST_PROT_UNREACHABLE	(IP_STATUS_BASE + 4)#define IP_DEST_PORT_UNREACHABLE	(IP_STATUS_BASE + 5)#define IP_NO_RESOURCES				(IP_STATUS_BASE + 6)#define IP_BAD_OPTION				(IP_STATUS_BASE + 7)#define IP_HW_ERROR					(IP_STATUS_BASE + 8)#define IP_PACKET_TOO_BIG			(IP_STATUS_BASE + 9)#define IP_REQ_TIMED_OUT			(IP_STATUS_BASE + 10)#define IP_BAD_REQ					(IP_STATUS_BASE + 11)#define IP_BAD_ROUTE				(IP_STATUS_BASE + 12)#define IP_TTL_EXPIRED_TRANSIT		(IP_STATUS_BASE + 13)#define IP_TTL_EXPIRED_REASSEM		(IP_STATUS_BASE + 14)#define IP_PARAM_PROBLEM			(IP_STATUS_BASE + 15)#define IP_SOURCE_QUENCH			(IP_STATUS_BASE + 16)#define IP_OPTION_TOO_BIG			(IP_STATUS_BASE + 17)#define IP_BAD_DESTINATION			(IP_STATUS_BASE + 18)#define IP_ADDR_DELETED				(IP_STATUS_BASE + 19)#define IP_SPEC_MTU_CHANGE			(IP_STATUS_BASE + 20)#define IP_MTU_CHANGE				(IP_STATUS_BASE + 21)#define IP_UNLOAD					(IP_STATUS_BASE + 22)#define IP_GENERAL_FAILURE			(IP_STATUS_BASE + 50)#define MAX_IP_STATUS				IP_GENERAL_FAILURE#define IP_PENDING					(IP_STATUS_BASE + 255)// ICMP request options structuretypedef struct ip_info {     u_char Ttl;               /* Time To Live (used for traceroute) */     u_char Tos;               /* Type Of Service (usually 0) */     u_char Flags;             /* IP header flags (usually 0) */     u_char OptionsSize;       /* Size of options data (usually 0, max 40) */     u_char FAR *OptionsData;  /* Options data buffer */} IPINFO;//// ICMP reply data//// The reply buffer will have an array of ICMP_ECHO_REPLY// structures, followed by options and the data in ICMP echo reply// datagram received. You must have room for at least one ICMP// echo reply structure, plus 8 bytes for an ICMP header.// typedef struct icmp_echo_reply {     u_long Address;         /* source address */     u_long Status;          /* IP status value (see below) */     u_long RTTime;          /* Round Trip Time in milliseconds */     u_short DataSize;       /* reply data size */     u_short Reserved;         void FAR *Data;         /* reply data buffer */     struct ip_info Options; /* reply options */} ICMPECHO;class PICMPDLL : public PDynaLink{  PCLASSINFO(PICMPDLL, PDynaLink)  public:    PICMPDLL()      : PDynaLink("ICMP.DLL")    {      if (!GetFunction("IcmpCreateFile", (Function &)IcmpCreateFile) ||	  !GetFunction("IcmpCloseHandle", (Function &)IcmpCloseHandle) ||	  !GetFunction("IcmpSendEcho", (Function &)IcmpSendEcho))	Close();    }    // create an ICMP "handle"    // returns INVALID_HANDLE_VALUE on error     HANDLE (WINAPI *IcmpCreateFile)(void);    // close a handle allocated by IcmpCreateFile    // returns FALSE on error    BOOL (PASCAL *IcmpCloseHandle)(HANDLE handle);    // Send the ICMP echo command for a "ping"    DWORD (PASCAL *IcmpSendEcho)(	 HANDLE   handle,           /* handle returned from IcmpCreateFile() */	 u_long   destAddr,         /* destination IP address (in network order) */	 void   * sendBuffer,       /* pointer to buffer to send */	 WORD     sendLength,       /* length of data in buffer */	 IPINFO * requestOptions,   /* see structure definition above */	 void   * replyBuffer,      /* structure definitionm above */	 DWORD    replySize,        /* size of reply buffer */	 DWORD    timeout           /* time in milliseconds to wait for reply */    );} ICMP;#endif // _WIN32_WCEPICMPSocket::PICMPSocket(){  OpenSocket();}BOOL PICMPSocket::IsOpen() const{  return icmpHandle != NULL;}BOOL PICMPSocket::OpenSocket(){  return ICMP.IsLoaded() && (icmpHandle = ICMP.IcmpCreateFile()) != NULL;}BOOL PICMPSocket::Close(){  if (icmpHandle == NULL)     return TRUE;  PAssert(ICMP.IsLoaded(), PLogicError);  return ICMP.IcmpCloseHandle(icmpHandle);}const char * PICMPSocket::GetProtocolName() const{  return "icmp";}BOOL PICMPSocket::Ping(const PString & host){  PingInfo info;  return Ping(host, info);}BOOL PICMPSocket::Ping(const PString & host, PingInfo & info){  if (!ICMP.IsLoaded())    return SetErrorValues(NotOpen, EBADF);  // find address of the host  PIPSocket::Address addr;  if (!GetHostAddress(host, addr))    return SetErrorValues(BadParameter, EINVAL);  IPINFO requestOptions;  requestOptions.Ttl = info.ttl;     /* Time To Live (used for traceroute) */  requestOptions.Tos = 0;            /* Type Of Service (usually 0) */  requestOptions.Flags = 0;          /* IP header flags (usually 0) */  requestOptions.OptionsSize = 0;    /* Size of options data (usually 0, max 40) */  requestOptions.OptionsData = NULL; /* Options data buffer */  BYTE sendBuffer[32];  void * sendBufferPtr;  WORD sendBufferSize;  if (info.buffer != NULL) {    sendBufferPtr = (void *)info.buffer;    PAssert(info.bufferSize < 65535, PInvalidParameter);    sendBufferSize = (WORD)info.bufferSize;  }  else {    sendBufferPtr = sendBuffer;    sendBufferSize = sizeof(sendBuffer);  }  ICMPECHO * reply = (ICMPECHO *)malloc(sizeof(ICMPECHO)+sendBufferSize);  if (ICMP.IcmpSendEcho(icmpHandle,		        addr,		        sendBufferPtr, sendBufferSize,		        &requestOptions,		        reply, sizeof(ICMPECHO)+sendBufferSize,		        GetReadTimeout().GetInterval()) != 0) {    info.delay.SetInterval(reply->RTTime);    info.remoteAddr = Address((in_addr&)reply->Address);  }  GetHostAddress(info.localAddr);  switch (reply->Status) {    case IP_SUCCESS :      info.status = PingSuccess;      break;    case IP_DEST_NET_UNREACHABLE :      info.status = NetworkUnreachable;      break;    case IP_DEST_HOST_UNREACHABLE :      info.status = HostUnreachable;      break;    case IP_PACKET_TOO_BIG :      info.status = PacketTooBig;      break;    case IP_REQ_TIMED_OUT :      info.status = RequestTimedOut;      break;    case IP_BAD_ROUTE :      info.status = BadRoute;      break;    case IP_TTL_EXPIRED_TRANSIT :      info.status = TtlExpiredTransmit;      break;    case IP_TTL_EXPIRED_REASSEM :      info.status = TtlExpiredReassembly;      break;    case IP_SOURCE_QUENCH :      info.status = SourceQuench;      break;    case IP_MTU_CHANGE :      info.status = MtuChange;      break;    default :      info.status = GeneralError;  }  free(reply);  return info.status == PingSuccess;}PICMPSocket::PingInfo::PingInfo(WORD id){  identifier = id;  sequenceNum = 0;  ttl = 255;  buffer = NULL;  status = PingSuccess;}// End Of File ///////////////////////////////////////////////////////////////

⌨️ 快捷键说明

复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?