www.pudn.com > PortScan_sjtu.rar > ICMP_ECHO.cpp
// ICMP_ECHO.cpp : 定义控制台应用程序的入口点。 // #include "stdafx.h" #include#include #include "ICMP_ECHO.h" #pragma comment(lib,"ws2_32.lib") void ICMP_ECHO::Init_Header(char* buf) { ICMP_HDR *icmp = NULL; char* datapart = NULL; icmp = (ICMP_HDR*)buf; //初始化ICP头 icmp->icmp_type = 8; icmp->icmp_code = 0; icmp->icmp_id = GetCurrentProcessId(); icmp->icmp_checksum = 0; icmp->icmp_sequence = 0; icmp->icmp_timestamp=GetTickCount(); datapart = buf + sizeof(ICMP_HDR); memset(datapart, 'E', 32); icmp->icmp_checksum = checksum((USHORT *)buf,sizeof(ICMP_HDR)+32); } USHORT ICMP_ECHO::checksum(USHORT *buffer, int size) { unsigned long cksum=0; while (size > 1) { cksum += *buffer++; size -= sizeof(USHORT); } if (size) { cksum += *(UCHAR*)buffer; } cksum = (cksum >> 16) + (cksum & 0xffff); cksum += (cksum >>16); return (USHORT)(~cksum); } int ICMP_ECHO::Ping(char* IP_dest,u_int time_out, char* msg) { WSADATA wsd; ICMP_HDR *icmp_send = NULL; ICMP_HDR *icmp_rev = NULL; SOCKADDR_STORAGE dest; struct sockaddr_in src_addr; SOCKET s; char send_buf[sizeof(ICMP_HDR)+32]; char recv_buf[sizeof(IPV4_HDR)+sizeof(ICMP_HDR)+32]; char tempMsg[50]; tempMsg[0] = '\0'; if (WSAStartup(MAKEWORD(2,2), &wsd) != 0) { sprintf(tempMsg,"Ping %s: WSAStartup() failed: %d\r\n", IP_dest,WSAGetLastError()); strcat(msg,tempMsg); return -1; } s = socket(AF_INET,SOCK_RAW,IPPROTO_ICMP); //ICMP协议socket if (s==INVALID_SOCKET) { sprintf(tempMsg,"Ping %s:无法建立套结字 \r\n", IP_dest); strcat(msg,tempMsg); WSACleanup(); return (-1); } //设置套接字的超时时间 int ret_code = setsockopt(s, SOL_SOCKET, SO_RCVTIMEO, (char*)&time_out, sizeof(time_out)); if (ret_code==SOCKET_ERROR) { sprintf(tempMsg,"Ping %s:ICMP设置接收超时时间失败 \r\n", IP_dest); strcat(msg,tempMsg); closesocket(s); WSACleanup(); return (-1); } ret_code = setsockopt(s, SOL_SOCKET, SO_SNDTIMEO, (char*)&time_out, sizeof(time_out)); if (ret_code==SOCKET_ERROR) { sprintf(tempMsg,"Ping %s:ICMP设置发送超时时间失败 \r\n", IP_dest); strcat(msg,tempMsg); closesocket(s); WSACleanup(); return (-1); } ((SOCKADDR_IN *)&dest)->sin_family = AF_INET; //初始化目标地址 ((SOCKADDR_IN *)&dest)->sin_port = htons(0); ((SOCKADDR_IN *)&dest)->sin_addr.s_addr = inet_addr(IP_dest); Init_Header(send_buf); //初始化ICMP报文 ret_code = sendto(s,send_buf,sizeof(ICMP_HDR)+32,0,(SOCKADDR *)&dest,sizeof(dest)); //发送ICMP报文 if (ret_code==SOCKET_ERROR) { sprintf(tempMsg,"Ping %s:ICMP发送失败 \r\n", IP_dest); strcat(msg,tempMsg); closesocket(s); WSACleanup(); return(-1); } int src_len = sizeof(src_addr); ret_code = recvfrom(s, (char *)&recv_buf, sizeof(recv_buf), 0, (SOCKADDR *)&src_addr, &src_len); //接受回复 if (ret_code==SOCKET_ERROR) { sprintf(tempMsg,"Ping %s: 主机关机 \r\n", IP_dest); strcat(msg,tempMsg); closesocket(s); WSACleanup(); return(-1); } int recv_len = ret_code; //分析回复报文 if (recv_len < sizeof(IPV4_HDR)){ sprintf(tempMsg,"Ping %s: ICMP Reply ERROR! \r\n", IP_dest); strcat(msg,tempMsg); closesocket(s); WSACleanup(); return(-1); } IPV4_HDR *ip_hdr_recv = (IPV4_HDR *)recv_buf; //IP头分析 int ip_hdr_recv_len = ip_hdr_recv->ip_verlen & 0x0F; ip_hdr_recv_len = (ip_hdr_recv_len) << 2; if (checksum((u_short *)ip_hdr_recv, ip_hdr_recv_len)) { sprintf(tempMsg,"Ping %s: ICMP Reply IP header checksum is wrong! \r\n", IP_dest); strcat(msg,tempMsg); closesocket(s); WSACleanup(); return(-1); } if (recv_len < (ip_hdr_recv_len + sizeof(ICMP_HDR))) { sprintf(tempMsg,"Ping %s: ICMP Reply len 不正确! \r\n", IP_dest); strcat(msg,tempMsg); closesocket(s); WSACleanup(); return(-1); } ICMP_HDR *icmp_hdr_recv = (ICMP_HDR *) (recv_buf + ip_hdr_recv_len); //ICMP头分析 if (icmp_hdr_recv->icmp_type !=0 ){ //是否对ping回复 sprintf(tempMsg,"Ping %s: ICMP Reply type 不正确! \r\n", IP_dest); strcat(msg,tempMsg); closesocket(s); WSACleanup(); return(-1); } if (icmp_hdr_recv->icmp_id != (u_short)GetCurrentProcessId() ){ //是否对本进程回复 sprintf(tempMsg,"Ping %s: ICMP Reply 不是返回本进程的! \r\n", IP_dest); strcat(msg,tempMsg); closesocket(s); WSACleanup(); return(-1); } sprintf(tempMsg,"Ping %s: 主机开机! \r\n", IP_dest); strcat(msg,tempMsg); closesocket(s); WSACleanup(); return 0; }