[计算机]发现网络中的活动主机报告及源代码.doc

上传人:爱问知识人 文档编号:5119584 上传时间:2020-02-04 格式:DOC 页数:26 大小:137.01KB
返回 下载 相关 举报
[计算机]发现网络中的活动主机报告及源代码.doc_第1页
第1页 / 共26页
[计算机]发现网络中的活动主机报告及源代码.doc_第2页
第2页 / 共26页
[计算机]发现网络中的活动主机报告及源代码.doc_第3页
第3页 / 共26页
[计算机]发现网络中的活动主机报告及源代码.doc_第4页
第4页 / 共26页
[计算机]发现网络中的活动主机报告及源代码.doc_第5页
第5页 / 共26页
亲,该文档总共26页,到这儿已超出免费预览范围,如果喜欢就下载吧!
资源描述

《[计算机]发现网络中的活动主机报告及源代码.doc》由会员分享,可在线阅读,更多相关《[计算机]发现网络中的活动主机报告及源代码.doc(26页珍藏版)》请在三一文库上搜索。

1、目 录 一课程设计目的2二. 课程设计要求2三相关知识2四课程设计分析4五程序流程图7六程序运行结果截图10七. 课程设计心得10八.附录:参考文献 11一课程设计目的: IP协议的优点是简洁,但缺少差错控制和查询机制,而网际控制报文协议(ICMP)具有补充IP功能的作用。在网络管理中,常常要确定当前网络中处于活动状态的主机,这时可以通过使用ICMP的回送和回送响应消息来完成这项工作。本课程设计的目的就是编制程序,利用ICMP数据包,发现指定网段中的活动主机。通过课程设计,使学生更加熟悉ICMP报文的结构,对ICMP协议有更好的理解和认识。二课程设计要求: 设计程序,其功能是发送ICMP数据包

2、,以获取指定网段中的活动主机,并将结果显示在标准输出上。 程序的具体要求如下:1) 用命令行形式运行: scanhost Start_IP End_IP其中scanhost为程序名;Start_IP为被搜索网段的开始IP地址;End_IP为被搜索网段的结束IP地址。2)输出格式为: 活动主机1 活动主机2 三相关知识:编制程序前首先要对ICMP报文的格式有一定的了解,ICMP报文是在IP数据报内部传输的,其结构如图10-1所示: IP数据报 IP首部 ICMP报文ICMP报文的格式如图10-2所示:0 7 8 15 16 31(位)类型字段代码字段校验和字段(不同类型和代码有不同内容)所有报文

3、的前4个字节都是一样的,但是其它字节则互不相同。其中类型字段可以有15个不同的值,以描述特定类型的ICMP报文,某些ICMP报文还使用代码字段的值来进一步描述不用的条件。按验和字段为2字节,校验的范围是整个ICMP报文。检验和是必须的,其计算方法与IP协议头部校验和的计算方法一样。 各种类型的ICMP报文如图10-3所示(ICMP报文类型),不同类型由报文中的类型字段和代码字段来共同决定。类 型 代 码 描 述 0 0 回送响应(PING应答)3 目的不可达0 网络不可达1 主机不可达2 协议不可达3 端口不可达4 需要进行分片但设置了禁止分片比特5 源主机选择路由失败6 无法识别目的网络7

4、无法识别目的主机8 源主机被隔离9 目的网络被禁止10 目的主机被禁止11 由于服务类型(TOS),网络不可达12 由于服务类型(TOS),主机不可达13 由于过滤,通信被强行禁止14 主机越权15 优先权终止生效 4 0 源端被关闭(基本流控制)5 重定向0 对网络重定向1 对主机重定向2 对服务类型和网络重定向3 对服务类型和主机重定向 8 0 回送请求(PING请求)9 0 路由器通告10 0 路由器请求11 超时0 传输期间生存期减为01 数据报组装期间生存期减为012 参数问题0 各种IP头部错误1 缺少必须的选项13 0 时间戳请求14 0 时间戳应答15 0 信息请求(已作废)1

5、6 0 信息应答(已作废)17 0 地址掩码请求18 0 地址掩码应答10-3 ICMP报文类型本课程设计的目的是发现网络中的活动主机,就是使用ICMP的回送和回送响应消息发现网络中的活动主机,即Ping消息的请求和应答。那幺,发送的ICMP的数据包类型设置为回送请求(类型号为8)。四课程设计分析: 本程序使用原始套接字生成ICMP报文来进行活动主机的探查。这个程序使用的是回送请求与应答消息。程序的大致思想是把ICMP的数据包类型设置为回送请求,将它发送给网络上的一个IP地址,如果这个IP地址已经被占用的话,那幺使用位于这个IP地址的主机上的TCP/IP软件就能够接收到这个ICMP回送请求,从

6、而返回一个ICMP回送响应(类型号为0)信息。信息封装在一个IP包中,我们需要解析该IP包,从中找到ICMP数据信息。相反,如果这个IP地址没有人使用,那幺发送的ICMP回送请求在设定的延时内就不可能得到响应。 在初始化原始套接字之后,本程序就要开始在一个IP网段内寻找活动主机。因为要寻找的主机可能很多,为节省时间可以采用多线程编程。下面接结合核心代码对程序的具体实现进行讲解,同时为使程序流程更加清晰,去掉了错误检查等保护性代码。1.使用原始套接字 为了实现发送/监听ICMP报文,必须使用原始套接字,创建原始套接字的代码如下: socket sockRaw; sockRaw = WSAocke

7、t (AF_INET, sock_Raw, IPPROTO_ICMP, NULL, 0, WSA_FLAG_OVERLAPPED); 在WSASocket函数中,我们使用IPPROTO_ICMP表示接收ICMP数据包,为了使用发送超时设置(设置SO_RCVTIMEO或SO_SNDTIMEO),必须将标志位置为WSA_FLAG_OVERLAPPED。然后调用setsockopt函数设置读取延迟。 Int timeout=1000;Setsockopt(sockRaw,SQL_SOCKET,SO_RCVTIMEO,(char*)&timeout,sizeof(timeout);setsockopt

8、(sockRaw,SQL_socket,SO_SNDTIMEO,(char*)&timeout,sizeof(timeout) 在setsockopt函数中,sockRaw是之前创建的原始套接字,设置SQL_SOCKET表明使用基本套接字处理ICMP报文。设置SO_RCVTIMEO表示使用接收超时设置,SO_SNDTIMEO表示使用发送超时设置,在这里,超时时间均设置为1000ms。 2定义IP头部和ICMP头部的数据结构 由于socket发送/捕获的是IP包,因此要分别定义IP头部的数据结构ICMP头部数据结构。 /IP报头的数据结构 typedef struct iphdrunsigned

9、 int headlen:4; /IP头长度unsigned int version:4; /IP版本号unsigned char tos; /服务类型unsigned short totallen; /IP包总长度 unsigned short id; /ID号unsigned short flag; /标记unsigned char ttl; /生存时间unsigned char prot; /协议(UDP TCP)nsigned short checksum; /校验和unsigned int sourceIP; /源IPunsigned int destIP; /目的IPIpHeade

10、r;/ICMP头部的数据结构typedef struct icmphdr BYTE type; /ICMP类型码,回送请求的类型码为8 BYTE code; /子类型码,保存与特定ICMP报文类型相关细节信息 USHORT checksum; /校验和 USHORT id; /ICMP报文ID号(一般用进程号作ID) USHORT seq; /ICMP数据报的序列号IcmpHeader;3填充并发送回送请求类型的ICMP报文 为了使收到数据包的目的主机发送响应,我们需要向目的主机发送回送请求类型的ICMP报文。从图10-3中可知,回送请求的类型号为8。因此ICMP报文的填充代码如下:#defi

11、ne ICNP_ECHO 8 /请求回送#define DEF_PACKET_SIZE 32 /缺省数据报长度#define MAX_PACKET 1024 /最大数据块长度char icmp_dataMAX_PACKET; /ICMP数据报最大可能的长度memset(icmp_data,0,MAX_PACKET); /将数据报清空初始化int datasize=DEF_PACKET_SIZE; /ICMP数据报报文体的缺省长度datasize+=sizeof(IcmpHeader); /再加上ICMP头部的长度IcmpHeader*icmp_hdr:Char *datapart;Icmp_h

12、dr = (IcmpHeader*)icmp_data;Icmp_hdr-type = ICMP_ECHO; /设置类型Icmp_hdr-id = (USHORT)GetCurrentThreadId(); /设置其ID号为当前线程号Datapart = icmp_data + sizeof(IcmpHeader); /计算出数据报的数据部分Memset(datapart,A,datasize-sizeof(IcmpHeader); /填入数据(IcmpHeader*)icmp_data)-seq= 0; /序列号为0(IcmpHeader*)icmp_data)-checksum = 0;

13、/先将校验和置0(IcmpHeader*)icmp_data)-checksum = checksum(USHORT*)icmp_data,datasize);checksum为校验和的函数,设校验和初值为0 ,然后对数据每16为求异或,结果取反,便得校验和。其代码如下: USHORT checksum(USHORT *buffer, int size) 计算校验和 unsigned long cksum = 0; while(size1) cksum+=*buffer+; size -=sizeof(USHORT);if(size) cksum += (UCHAR*)buffer; cksu

14、m = (cksum 16)+(cksum & 0xffff);cksum +=(cksum 16);return(USHORT)(-cksum); 填充ICMP报文之后,应在ICMP报文之前加上IP报头并发送出去。可调用下面的代码发送数据包。注意,这里的DEST是填入目的主机IP地址的一个sockaddr_in数据结构,IPSTRING是目的主机的IP地址字符串。 Struct sockaddr_in dest; dest.sin_family = AF_INET; dest.sin_addr.s_addr = inet_addr(IP_STRING); /填入搜索的IP地址 sendto(

15、sockRaw,icmp_data,datasize,0,(sockaddr*)&dest,sizeof(dest);4.解析数据包如果所Ping的目的主机所在,那么它会发送一个回送应答包。这是一个IP包,收到后解析此数据包并获取其中的ICMP信息。根据IP报头信息中的IP报头长度字段,就可以得到ICMP报文的真实地址。ICMP数据包中的IP地址就是活动主机的IP。代码如下: #define ICMP_MIN 8 /ICMP报文头长度(最小ICMP报文长度) #define MAX_PING_PACKET_SIZE (MAX_PACKET + SIZEOF(IPHeader) char *re

16、cvbuf=new charMAX_PING_PACKET_SIZE; /保证大与发送包的大小 /from是一个sockaddr_in数据结构,用于保存响应的目的的主机的地址 struct sockaddr_in from; int fromlen = sizeof(from); int bytes = recvfrom(sockRaw,recvbuf,MAX_PACKET, 0,(struck sockaddr*)&from),&fromlen); IpHeader *iphdr; IcmpHeader *icmphdr; Unsigned short iphdrlen; Iphdr=(Ip

17、header *)buf; Iphdrlen = iphdr-headlen*4 ; /IP报头的长度 Icmphdr=(Icmpheader *)(buf+iphdrlen); /跳过IP报头 /数据包太短,丢弃 if(bytestype !=ICMP_ECHO_REPLY) return; /Id号不相符,丢弃 if(icmphdr-id!=(USHOT)GetCurrentThreadId() return; /输出正在使用的IP地址。 Cout”活动主机:”sin_addr)endl;五程序流程图:一个用多线程实现的程序在第三部分中给出(课程设计分析中的第三部分),以下分别是子程序流程

18、图和主程序流程图(程序见附录):1子程序流程图:开 始填充ICMP数据报发送数据报接收数报去掉IP报头,获取ICMP信息数据包太短? Y N不是回送响应? Y NID不符合? Y N输出数据报中的IP地址 结 束 图1.子程序流程图2主程序流程图:开 始将Start_IP添入到dest中起始IP地址Start_IP结束IP地址End_IP建立并初始化目的主机的Sockaddr_in数据结构dest构造原始套接字,并初始化Start_IPEnd_IP? N Y Y线程数目太多?等待一定时间 N创建一个线程并执行Start_IP+ Y 还有线程在执行?等待一定时间 N结 束 图2.主程序流程图六程

19、序运行结果截图: 图3.运行结果七课程设计心得:附录:参考文献1 吴功宜、胡晓英等.计算机网络课程设计,北京:机械工业出版社,2007.122 胡晓英等;计算机网络课程设计;北京:机械工业出版社,2005.93 郭国强等;计算机网络与Internet教程;北京:清华出版社,2006.114 杨丰瑞 杨丰任;实用教程最新计算机网络;北京:中国铁道出版社,2001.7源代码:#pragma pack(4)/#include stdafx.h#pragma comment (lib,Ws2_32.lib)#define WIN32_LEAN_AND_MEAN#include #include #in

20、clude #include #include #include #include typedef struct iphdrunsigned 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;

21、typedef struct icmphdrBYTE type;BYTE code;USHORT checksum;USHORT id;USHORT seg;IcmpHeader;#define ICMP_RCHO 8#define ICMP_RCHO_REPLY 0#defineICMP_MIN 8#define STATUS_FAILED 0xFFFF#defineDEF_PACKET_SIZE 32#define MAX_PACKET 1024#define MAX_PING_PACKET_SIZE (MAX_PACKET+sizeof(IpHeader)void fill_icmp_d

22、ata(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 charMAX_PING_PACKET_SIZE;unsigned int addr=0;long Thread

23、NumCounter=0,ThreadNumLimit=20;long *aa=&ThreadNumCounter;void main(int argc,char *argv)/*if(argc!=3)cout输入格式错误: start_ip end_ipendl;return;*/if(WSAStartup(MAKEWORD(2,1),&wsaData)!=0)coutWASStartup failedGetLastError()endl;ExitProcess(STATUS_FAILED);sockRaw=WSASocket(AF_INET,SOCK_RAW,IPPROTO_ICMP,NU

24、LL,0,WSA_FLAG_OVERLAPPED);if(sockRaw=INVALID_SOCKET)coutWASSocketet() faliedWSAGetLastError()endl;ExitProcess(STATUS_FAILED);int timeout=1000;int bread=setsockopt(sockRaw,SOL_SOCKET,SO_RCVTIMEO,(char *)&timeout,sizeof(timeout);if(bread=SOCKET_ERROR)coutFAILED TO SEY RECV TIMEOUTWSAGetLastError()endl

25、;ExitProcess(STATUS_FAILED); timeout=1000; bread=setsockopt(sockRaw,SOL_SOCKET,SO_SNDTIMEO,(char *)&timeout,sizeof(timeout); if(bread=SOCKET_ERROR)coutFAILED TO SEY RECV TIMEOUTWSAGetLastError()endl;ExitProcess(STATUS_FAILED);memset(&dest,0,sizeof(dest);unsigned long startIP,endIP;dest.sin_family=AF

26、_INET;dest.sin_addr.s_addr=inet_addr(argv1);startIP=inet_addr(argv1);end.sin_family=AF_INET;end.sin_addr.s_addr=inet_addr(argv2);endIP=inet_addr(argv2);HANDLE hThread;while(htonl(startIP)ThreadNumLimit)Sleep(5000);continue;DWORD ThreadID;sockaddr_in *pIPAddrTemp=new (sockaddr_in);if(!pIPAddrTemp)cou

27、tmemory alloc failedendl;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

28、_addr.s_addr=startIP;while(ThreadNumCounter!=0)Sleep(2000);return;couterrortype=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;IcmpHea

29、der *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*)

30、buffer;cksum=(cksum16)+(cksum& 0xffff);cksum+=(cksum16);return (USHORT)(cksum);DWORD WINAPI FindIP(LPVOID pIPAddrTemp)InterlockedIncrement(aa);char icmp_dataMAX_PACKET;memset(icmp_data,0,MAX_PACKET);int datasize=DEF_PACKET_SIZE;datasize+=sizeof(IcmpHeader);fill_icmp_data(icmp_data,datasize);(IcmpHea

31、der*)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)couttimed outendl

32、;coutsendto failiesWSAGetLastError()endl;ExitProcess(STATUS_FAILED);n=1;if(WSAGetLastError()=WSAETIMEDOUT)couttimed outendl;ExitProcess(STATUS_FAILED);n=1;if(bwrotedatasize)coutWortebwrotebytesendl;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)couttimed outendl;coutrecvfrom faliedWSAGetLastError()endl;ExitProcess(STATUS_FAILED);n=1;if(n=0)decode_resp(recvbuf,bread,&from);InterlockedDecrement(aa);return 0;25

展开阅读全文
相关资源
猜你喜欢
相关搜索

当前位置:首页 > 工程管理


经营许可证编号:宁ICP备18001539号-1