利用ICMP探测网络活跃主机的课程设计实践

需积分: 10 20 下载量 130 浏览量 更新于2024-07-29 6 收藏 163KB DOC 举报
本项目是关于计算机网络课程设计的一项任务,其核心目标是利用Internet Control Message Protocol (ICMP) 的回送请求和响应机制来检测网络中的活动主机。设计的主要内容是编写一个名为`scanhost`的程序,该程序接收用户输入的开始IP地址(Start_IP)和结束IP地址(End_IP),然后通过发送ICMP回送请求(类型字段为8)来探测网络中的活跃设备。程序运行时,用户会看到标准输出设备上显示的活动主机列表,格式为活动主机的IP地址。 课程设计的目的是提升对ICMP协议的理解,特别是ICMP报文的结构。ICMP报文是一种在网络中传递错误报告、路由信息和网络状态询问的协议,它补充了IP协议的功能,对于网络管理来说,能帮助确认网络中哪些主机是在线的。通过这个实践项目,学生可以锻炼使用网络知识解决实际问题的能力。 设计要求非常明确,程序需满足以下几点: 1. 命令行操作:用户通过`scanhost Start_IP End_IP`的形式启动程序,例如`scanhost 192.168.0.1 192.168.0.100`。 2. 输出格式:程序返回的结果仅包含活动主机的IP地址,按照发现的顺序列出。 在设计过程中,关键在于理解ICMP报文的结构,包括其头部的类型字段(用于标识报文类型,如回送请求)、代码字段(进一步描述特定条件)以及校验和字段(确保数据的完整性)。不同类型的ICMP报文,如回送请求和响应,具有各自的字段值和功能。程序需要根据这些细节来构建和发送数据包,以有效地进行网络扫描。 这个课程设计不仅涉及到编程技能,也强调了理论知识的实际应用,帮助学生掌握如何在实践中运用网络通信协议来监控和管理网络环境。
2008-12-21 上传
#pragma pack(4) //#include "stdafx.h" #pragma comment (lib,"Ws2_32.lib") #define WIN32_LEAN_AND_MEAN #include #include #include #include #include #include #include typedef struct iphdr { unsigned int headlen:4; unsigned int version:4; unsigned char tos; unsigned short totallen; unsigned short id; unsigned short falg; unsigned char ttl; unsigned char prot; unsigned short checksum; unsigned int sourceIP; unsigned int destIP; }IpHeader; typedef struct icmphdr { BYTE type; BYTE code; USHORT checksum; USHORT id; USHORT seg; }IcmpHeader; #define ICMP_RCHO 8 #define ICMP_RCHO_REPLY 0 #define ICMP_MIN 8 #define STATUS_FAILED 0xFFFF #define DEF_PACKET_SIZE 32 #define MAX_PACKET 1024 #define MAX_PING_PACKET_SIZE (MAX_PACKET+sizeof(IpHeader)) void fill_icmp_data(char *,int); USHORT checksum(USHORT *,int); void decode_resp(char *,int,struct sockaddr_in *); DWORD WINAPI FindIP(LPVOID pIPAddrTemp); WSADATA wsaData; SOCKET sockRaw; struct sockaddr_in dest,from,end; int fromlen =sizeof(from); char *recvbuf=new char[MAX_PING_PACKET_SIZE]; unsigned int addr=0; long ThreadNumCounter=0,ThreadNumLimit=20; long *aa=&ThreadNumCounter; void main(int argc,char *argv[]) { /*if(argc!=3) { cout<<"输入格式错误: start_ip end_ip"<<endl; return; }*/ if(WSAStartup(MAKEWORD(2,1),&wsaData)!=0) { cout<<"WASStartup failed"<<GetLastError()<<endl; ExitProcess(STATUS_FAILED); } sockRaw=WSASocket(AF_INET,SOCK_RAW,IPPROTO_ICMP,NULL,0,WSA_FLAG_OVERLAPPED); if(sockRaw==INVALID_SOCKET) { cout<<"WASSocketet() falied"<<WSAGetLastError()<<endl; ExitProcess(STATUS_FAILED); } int timeout=1000; int bread=setsockopt(sockRaw,SOL_SOCKET,SO_RCVTIMEO,(char *)&timeout,sizeof(timeout)); if(bread==SOCKET_ERROR) { cout<<"FAILED TO SEY RECV TIMEOUT"<<WSAGetLastError()<<endl; ExitProcess(STATUS_FAILED); } timeout=1000; bread=setsockopt(sockRaw,SOL_SOCKET,SO_SNDTIMEO,(char *)&timeout,sizeof(timeout)); if(bread==SOCKET_ERROR) { cout<<"FAILED TO SEY RECV TIMEOUT"<<WSAGetLastError()<<endl; ExitProcess(STATUS_FAILED); } memset(&dest,0,sizeof(dest)); unsigned long startIP,endIP; dest.sin_family=AF_INET; dest.sin_addr.s_addr=inet_addr(argv[1]); startIP=inet_addr(argv[1]); end.sin_family=AF_INET; end.sin_addr.s_addr=inet_addr(argv[2]); endIP=inet_addr(argv[2]); HANDLE hThread; while(htonl(startIP)ThreadNumLimit) { Sleep(5000); continue; } DWORD ThreadID; sockaddr_in *pIPAddrTemp=new (sockaddr_in); if(!pIPAddrTemp) { cout<<"memory alloc failed"<<endl; return ; } *pIPAddrTemp=dest; clock_t start; start=clock(); hThread=CreateThread(NULL,NULL,FindIP,(LPVOID)pIPAddrTemp,NULL,&ThreadID); long i=60000000L; while(i--); TerminateThread(hThread,0); InterlockedDecrement(aa); memset(&from,0,sizeof(from)); startIP=htonl(htonl(startIP)+1); dest.sin_addr.s_addr=startIP; } while(ThreadNumCounter!=0) { Sleep(2000); return; cout<<"error"<type=ICMP_RCHO; icmp_hdr->id=(USHORT)GetCurrentThreadId(); datapart=icmp_data+sizeof(IcmpHeader); memset(datapart,'A',datasize-sizeof(IcmpHeader)); } void decode_resp(char *buf,int bytes,struct sockaddr_in *from) { IpHeader *iphdr; IcmpHeader *icmphdr; unsigned short iphdrlen; iphdr=(IpHeader*) buf; iphdrlen=iphdr->headlen*4; icmphdr=(IcmpHeader *)(buf+iphdrlen); if(bytestype!=ICMP_RCHO_REPLY)return; if(icmphdr->id!=(USHORT)GetCurrentThreadId())return; cout<<"活动主机: "<<endl; cout<<" "<sin_addr)<1) { cksum+=*buffer++; size-=sizeof(USHORT); } if(size) { cksum+=*(UCHAR*)buffer; } cksum=(cksum>>16)+(cksum& 0xffff); cksum+=(cksum>>16); return (USHORT)(~cksum); } DWORD WINAPI FindIP(LPVOID pIPAddrTemp) { InterlockedIncrement(aa); char icmp_data[MAX_PACKET]; memset(icmp_data,0,MAX_PACKET); int datasize=DEF_PACKET_SIZE; datasize+=sizeof(IcmpHeader); fill_icmp_data(icmp_data,datasize); ((IcmpHeader*)icmp_data)->checksum=0; ((IcmpHeader*)icmp_data)->seg=0; ((IcmpHeader*)icmp_data)->checksum=checksum((USHORT*)icmp_data,datasize); int bwrote=sendto(sockRaw,icmp_data,datasize,0,(struct sockaddr *)pIPAddrTemp,sizeof(dest)); int n=0; if(bwrote==SOCKET_ERROR) { if(WSAGetLastError()==WSAETIMEDOUT) { cout<<"timed out"<<endl; } cout<<"sendto failies"<<WSAGetLastError()<<endl; ExitProcess(STATUS_FAILED); n=1; } if(WSAGetLastError()==WSAETIMEDOUT) { cout<<"timed out"<<endl; ExitProcess(STATUS_FAILED); n=1; } if(bwrote<datasize) { cout<<"Worte"<<bwrote<<"bytes"<<endl; ExitProcess(STATUS_FAILED); n=1; } int bread=recvfrom(sockRaw,recvbuf,MAX_PING_PACKET_SIZE,0,(struct sockaddr *)&from,&fromlen); if(bread==SOCKET_ERROR) { if(WSAGetLastError()==WSAETIMEDOUT) { cout<<"timed out"<<endl; } cout<<"recvfrom falied"<<WSAGetLastError()<<endl; ExitProcess(STATUS_FAILED); n=1; } if(n==0) { decode_resp(recvbuf,bread,&from); InterlockedDecrement(aa); } return 0; }