ping 程式(vc6.0 原始套接字實現)
阿新 • • 發佈:2019-02-01
#include <stdio.h> #include <WINSOCK2.H> #include <windows.h> #include <ws2tcpip.h> //IP_TTL #pragma comment(lib,"ws2_32.lib") //ICMP首部結構體 typedef struct tagICMPHEADER { unsigned char type;//型別 unsigned char code;//程式碼 unsigned short checknum;//檢驗和 unsigned short id;//識別符號 unsigned short seq_num;//序列號 }ICMPHEADER; //IP首部結構體 typedef struct _ip_hdr { unsigned char ihl:4; //首部長度 unsigned char version:4, //版本 unsigned char tos; //服務型別 unsigned short tot_len; //總長度 unsigned short id; //標誌 unsigned short frag_off; //分片偏移 unsigned char ttl; //生存時間 unsigned char protocol; //協議 unsigned short chk_sum; //檢驗和 struct in_addr srcaddr; //源IP地址 struct in_addr dstaddr; //目的IP地址 }IPHEADER; //計算檢驗和 unsigned short checksum(unsigned short *buffer, int size) { unsigned long cksum = 0; // 將所有的16數相加 while (size > 1) { cksum += *buffer++; size -= sizeof(unsigned short); } if (size) //加上最後一個BYTE { cksum += *(unsigned char*)buffer; } while (cksum>>16) { cksum = (cksum & 0xffff) + (cksum >> 16); } return (unsigned short)~cksum; } int main() { WSADATA wsadata; if(WSAStartup(MAKEWORD(2,2),&wsadata)!=0) { printf("初始化socket dll失敗\n"); return 1; } //設定ICMP首部內容 ICMPHEADER icmp_hdr; icmp_hdr.type=8; icmp_hdr.code=0; icmp_hdr.checknum=0; icmp_hdr.id=(unsigned short)GetCurrentProcessId(); icmp_hdr.seq_num=0; //計算檢驗和 icmp_hdr.checknum=checksum((unsigned short*)&icmp_hdr,sizeof(icmp_hdr)); //設定原始套接字 SOCKET sock=WSASocket(AF_INET,SOCK_RAW,IPPROTO_ICMP,NULL,0,0); if(INVALID_SOCKET==sock) { printf("建立socket失敗\n"); WSACleanup(); return 1; } int ttl=255; //設定TTL為255 if(setsockopt(sock,IPPROTO_IP,IP_TTL,(const char*)&ttl,sizeof(ttl))==SOCKET_ERROR) { printf("set TTL error!\n"); WSACleanup(); return 2; } //目標地址 SOCKADDR_IN Dest_addr; memset(&Dest_addr,0,sizeof(Dest_addr)); Dest_addr.sin_family=AF_INET; Dest_addr.sin_addr.S_un.S_addr=inet_addr("192.168.1.1"); //傳送ICMP請求報文 int status=sendto(sock,(const char*)&icmp_hdr,sizeof(icmp_hdr),0,(SOCKADDR*)&Dest_addr,sizeof(Dest_addr)); if(SOCKET_ERROR==status) { printf("sent error!\n"); shutdown(sock,SD_BOTH); closesocket(sock); WSACleanup(); return 3; } int size=60+sizeof(ICMPHEADER); char *buffer=(char*)malloc(size); memset(buffer,0,size); int des=sizeof(SOCKADDR_IN); //接受ICMP迴應報文並分析 while (true) { recvfrom(sock,buffer,size,0,(SOCKADDR*)&Dest_addr,&des); ICMPHEADER *p=(ICMPHEADER*)((char*)buffer+((IPHEADER*)buffer)->ihl*4); if(p->type==0) { if(p->id==icmp_hdr.id) { printf("ping %s成功\n",inet_ntoa(Dest_addr.sin_addr)); break; } } else { printf("ping %s不成功\n",inet_ntoa(Dest_addr.sin_addr)); break; } } shutdown(sock,SD_BOTH); closesocket(sock); WSACleanup(); return 0; }