|
void useage() { printf("******************************************\n"); printf("ICMPPing\n"); printf("\t Written by Refdom\n"); printf("\t Email: refdom@263.net\n"); printf("Useage: ICMPPing.exe Target_ip \n"); printf("*******************************************\n"); }
void DecodeHeader(char*, int);
void main(int argc, char* argv[]) { ICMP_HEADER icmpHeader; int rect; WSADATA WSAData; SOCKET sock; SOCKADDR_IN addr_in,addr_from; char recvbuf[1024];
useage(); if (argc!=2) { exit(0); }
if (WSAStartup(MAKEWORD(2,2), &WSAData) != 0 ) { printf ("WSAStartup Error!\n"); exit(0); }
sock= socket(AF_INET, SOCK_RAW, IPPROTO_ICMP); int nTimeOut = 2000; setsockopt(sock, SOL_SOCKET, SO_SNDTIMEO, (char*)&nTimeOut, sizeof(nTimeOut)); setsockopt(sock, SOL_SOCKET, SO_RCVTIMEO, (char*)&nTimeOut, sizeof(nTimeOut)); memset(&addr_in, 0, sizeof(addr_in)); addr_in.sin_family = AF_INET; addr_in.sin_addr.S_un.S_addr = inet_addr(argv[1]);
if (addr_in.sin_addr.S_un.S_addr == INADDR_NONE) { struct hostent *host = NULL; if ((host = gethostbyname(argv[1])) != NULL) { memcpy(&(addr_in.sin_addr), host->h_addr, host->h_length); } } // memset(&icmpHeader, 0, sizeof(icmpHeader)); icmpHeader.i_type = 8; icmpHeader.i_code = 0; icmpHeader.i_cksum = 0; icmpHeader.i_id = (USHORT)GetCurrentProcessId(); icmpHeader.i_seq = 0; icmpHeader.timestamp = GetTickCount(); icmpHeader.i_cksum = checksum((USHORT*)&icmpHeader, sizeof(icmpHeader));
rect = sendto(sock, (char*)&icmpHeader, sizeof(icmpHeader), 0, (sockaddr*)&addr_in, sizeof(addr_in)); int addr_from_len; addr_from_len = sizeof(addr_from); rect = recvfrom(sock, recvbuf, sizeof(recvbuf), 0, (sockaddr*)&addr_from, &addr_from_len); DecodeHeader(recvbuf, rect); closesocket(sock); WSACleanup(); }
void DecodeHeader(char* buf, int len) { ICMP_HEADER *icmpHeader; IP_HEADER *ipHeader; IN_ADDR addr; icmpHeader = (ICMP_HEADER*)(buf+20); DWORD Time1;
Time1 = GetTickCount(); ipHeader = (IP_HEADER*)malloc(20); memcpy(ipHeader, buf, 20); addr.S_un.S_addr = ipHeader->sourceIP; if (icmpHeader->i_type != 0) { printf("No replay!\n"); } if (icmpHeader->i_id != (USHORT)GetCurrentProcessId()) { printf("other pocket!\n"); } printf("Reply from %s: Bytes= %d ", inet_ntoa(addr), len); printf("TTL = %d Time= %d ms.\n", ipHeader->ttl, Time1-icmpHeader->timestamp ); } (其中去掉了一些错误判断的地方,呵呵,节约空间) PING得到的结果包括字节数、反应时间、以及生存时间。Ping程序通过在ICMP报文数据中存放发送请求的时间来计算返回时间。当应答返回时,根据现在时间减去报文中存放的发送时间就得到反应时间了。生存时间(TTL),本来就存放在IP数据报的头部,直接就能够获取。我们能够根据TTL时间来大致判断目标主机的系统类型,以及我们需要到达目的地需要经过几个路由器等等。 但是普通的Ping命令只能对一台主机进行探测,如果是要判断一个大类的网络是否有哪些活动的机器的话,就需要制作一个用来大面积Ping的工具,当然,你可以改进上面的基本程序,或者使用多线程并发来满足大面积Ping的需要。 还有一个Tracert 命令,也非常有用,可以参考以前写的,这里就不再罗嗦了。 关于ICMP协议的其他使用,比如,ICMP拒绝服务攻击等等,以后再讨论。
上一页 [1] [2] [3] [4] [5] [6] 下一页 |