123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244 |
- #pragma once
- #include <iostream>
- #include <iomanip>
- #include <fstream>
- #include <winsock2.h>
- #include <ws2tcpip.h>
- #include <stdio.h>
- #include <tchar.h>
- #include <stdarg.h>
- #include <string>
- #include <vector>
- #include <assert.h>
- #include <windows.h>
- #include <time.h>
- #include <atlbase.h>
- #include <conio.h>
- #include "mbnapi.h"
- #include <comdef.h>
- #include <IPHlpApi.h> //for mobileDial
- #pragma comment(lib, "ws2_32.lib")
- #pragma comment(lib, "mbnapi_uuid.lib")
- #include "SpBase.h"
- #if defined(SPBASE_API)
- #define printf(fmt, ...) \
- Dbg(fmt, __VA_ARGS__)
- #else
- #define printf(fmt, ...) \
- printf(fmt "\n", __VA_ARGS__)
- #endif
- //路由选项类型,占用3字节
- #define IP_RECORD_ROUTE 0x7
- //IP时间戳选项
- #define IP_TIMESTAMP 0x44
- #define DEFAULT_PACKET_SIZE 32
- #define MAX_PACKET 1024 + 12 + 20 + 1
- #define MAX_IP_HDR_SIZE 60
- //回送请求或回答
- #define ICMP_ECHO 8
- #define ICMP_ECHO_REPLY 0
- #define MAX_UNSIGNED_SHORT 65535
- #define DEFAULT_TIMEOUT 3000
- #define DEFAULT_INTERVAL 1000
- typedef struct _iphdr
- {
- //注意顺序,网络字节序,大端
- unsigned int h_len:4;
- unsigned int version:4;
- unsigned char tos; // type of service
- unsigned short total_len; // Total length of the packet
- unsigned short ident; // Unique identifier
- unsigned short frag_and_flags; // 标志和片偏移
- unsigned char ttl; // time to live
- unsigned char proto;
- unsigned short checksum;
- unsigned int sourceIP;
- unsigned int destIP;
- }IpHeader;
- #define DEFAULT_IP_HEAD_SIZE 20
- typedef struct _icmphdr
- {
- BYTE btType; //type of icmp
- BYTE btCode; // code of icmp 进一步定义查询或消息的类型 默认0
- USHORT usCksum; //16bits 对ICMP头内容的一个补余求和
- USHORT usId; //identification
- USHORT usSeq;
- //选项值
- ULONG ulTimestamp;
- }IcmpHeader;
- #define DEFAULT_ICMP_HEAD_SIZE sizeof(IcmpHeader)
- const double MAX_GSM_SIGNAL_STRENGTH = 31.0;
- class CTWPing
- {
- public:
- CTWPing();
- ~CTWPing(void);
- int Initial(const char* destIp, int nDataSize = 0, int nTimeout = 0, int nInterval = 0);
- //0 结束成功返回
- //1 创建套接字失败
- //2 超时达上限
- //3 其他错误达到上限
- int Ping();
- //0 结束成功返回
- //1 创建套接字失败
- //2 超时
- //3 其他错误
- //4 无效需要重新尝试
- int PingOnce();
- void TerminatePing()
- {
- m_bCancelPing = TRUE;
- }
- SOCKET m_hSocket;
- SOCKADDR_IN m_addrDest;
- SOCKADDR_IN m_addrSource;
- void Cleanup(bool bWSACleanup = false) //Consistent with FSM -Josephus@2017823 11:09:38
- {
- if(m_hSocket != INVALID_SOCKET)
- {
- closesocket(m_hSocket);
- m_hSocket = INVALID_SOCKET;
- }
- if(m_recvBuf != NULL)
- {
- HeapFree(GetProcessHeap(), 0, m_recvBuf);
- m_recvBuf = NULL;
- }
- if(m_icmpData != NULL)
- {
- HeapFree(GetProcessHeap(), 0, m_icmpData);
- m_icmpData = NULL;
- }
- while(bWSACleanup && TRUE)
- {
- if(WSACleanup() != ERROR_SUCCESS && WSAGetLastError() == WSANOTINITIALISED)
- break;
- }
- m_bInited = false;
- }
- bool IsValid() const
- {
- return m_bInited;
- }
- private:
- int m_nDataSize;
- int m_nTimeout;
- int m_nInterval;
- char m_szIP[128];
- char* m_icmpData;
- char* m_recvBuf;
- BOOL m_bCancelPing;
- bool m_bInited;
- USHORT m_usPacketSeqNo;
- USHORT GetCurrentSeqNo()
- {
- return m_usPacketSeqNo;
- }
- USHORT IncreaseCurSeqNo()
- {
- if(m_usPacketSeqNo < MAX_UNSIGNED_SHORT)
- {
- m_usPacketSeqNo++;
- }
- else
- {
- m_usPacketSeqNo = 0;
- }
- return m_usPacketSeqNo;
- }
- int InitICMPData();
- //-1 重置套接字并重新发送
- //-2 重新接收
- int DecodeICMPData(int bytes);
- int CreateSocket()
- {
- if(m_hSocket != INVALID_SOCKET)
- {
- closesocket(m_hSocket);
- m_hSocket = INVALID_SOCKET;
- }
- m_hSocket = WSASocket(AF_INET, SOCK_RAW, IPPROTO_ICMP, NULL, 0, WSA_FLAG_OVERLAPPED);
- if(m_hSocket == INVALID_SOCKET)
- {
- printf("WSASocket() failed with status %d", WSAGetLastError());
- return -1;
- }
- int bread = setsockopt(m_hSocket, SOL_SOCKET, SO_SNDTIMEO, (char*)&m_nTimeout, sizeof(m_nTimeout));
- if(bread == SOCKET_ERROR)
- {
- printf("Warning: Setsockopt(SO_SNDTIMEO) failed with status %d", WSAGetLastError());
- }
- bread = setsockopt(m_hSocket, SOL_SOCKET, SO_RCVTIMEO, (char*)&m_nTimeout, sizeof(m_nTimeout));
- if(bread == SOCKET_ERROR)
- {
- printf("Warning: Setsockopt(SO_RCVTIMEO) failed with status %d", WSAGetLastError());
- }
- m_usPacketSeqNo = 0;
- return 0;
- }
- void CloseSocket()
- {
- if(m_hSocket != INVALID_SOCKET)
- {
- closesocket(m_hSocket);
- m_hSocket = INVALID_SOCKET;
- }
- }
- USHORT CheckSum(USHORT* buffer, int nSize)
- {
- ULONG checkSum = 0;
- while(nSize > 1)
- {
- checkSum += *buffer++;
- nSize -= sizeof(USHORT);
- }
- if(nSize)
- {
- checkSum += *(UCHAR*)buffer;
- }
- checkSum = (checkSum >> 16) + (checkSum & 0xffff);
- checkSum += (checkSum >> 16);
- return (USHORT)(~checkSum);
- }
- };
|