1、课程设计()报告( 2011 / 2012 学年 第 二 学期)题目: 活动主机的检测 专 业 计算机科学与技术 学 生 姓 名 班 级 学 号 指 导 教 师 指 导 单 位 计算机学院 计算机系统与网络教学中心日 期 2012.06.112012.06.222指导教师成绩评定表学生姓名 班级学号 专业 计算机科学与技术评分内容 评分标准 优秀 良好 中等 差平时成绩 认真对待课程设计,遵守实验室规定,上机不迟到早退,不做和设计无关的事设计的科学、合理性功能丰富、符合题目要求 界面友好、外观漂亮、大方程序功能执行的正确性设计成果程序算法执行的效能设计报告正确合理、反映系统设计流程文档内容详实
2、程度设计报告文档格式规范、排版美观验收答辩简练、准确阐述设计内容,能准确有条理回答各种问题,系统演示顺利。评分等级指导教师简短评语指导教师签名 日期 2012.06.23备注 评分等级有五种:优秀、良好、中等、及格、不及格1 1题目一:活动主机的检测一、 课题内容和要求1. 设计内容 :根据协议规定的 ICMP 数据包的标准格式,编写程序向指定网段中的目的主机发送 ICMP 数据包,并对目的主机返回的数据包进行解析,以发现那些处于活动状态的主机。2. 设计要求(1)将目的主机的状态显示在屏幕上,具体格式:开始主机扫描活动主机:xx.xx.xx.xx活动主机:xx.xx.xx.xx (2)要求有
3、良好的编程规范和注释,编程所使用的操作系统、语言和编译环境不限,但是需在课程设计报告文档中予以说明。二、需求分析2.1 使用原始套接字,实现发送/监听 ICMP 报文2.2 由于 socket 发送/捕获的是 IP 包,因此要分别定义 IP 头部的数据结构和 ICMP 头部的数据结构。IP 头部的数据结构和 ICMP 头部的数据结构在概要设计中已有分析。2.3 填充并发送请求类型的 ICMP 报文, 填充 ICMP 报文后,应在 ICMP 报文之前加上 IP 报头并发送出去。2.4 解析数据包:如果所 ping 的目的主机存在,那么它会发出一个回送应答包。这是一个 IP 包,受到后解析此数据包
4、并获得其中的 ICMP 信息。根据 IP 报头信息中的 IP 报头长度字段,就可以得到 ICMP 报文的真实地址。ICMP 数据包中的 IP 地址就是活动主机的 IP。三、概要设计 2 23.1 设计原理本程序使用的原始套接字生成 ICMP 请求/应答报文来进行活动主机的探查。这个程序使用的是回送请求和应答消息。程序的大致思想是把 ICMP 的数据报类型设置为回送请求,将它发送给网络上的一个 IP 地址,如果这个 IP 地址已经被占用的话,那么使用位于这个 IP 地址的主机上的 TCP/IP 软件就能接受到这个 ICMP 回送请求,从而返回一个 ICMP 回送请求(类型号为 0)信息。信息封装
5、在一个 IP 包中,我们需要解析该 IP 包,从中找到 ICMP 数据信息,相反,如果这个 IP 地址没有人使用,那么发送的 ICMP 回送请求在设定的延时内就不可能得到响应。本设计的主体思想是使用 ICMPECHO 数据包来探测指定网段内的活动主机。具体方法是:通过简单的发送一个 ICMPECHO(Type 8)数据包到目标主机,如果ICMPECHOReply(ICMPtype0)数据包接受到,说明主机是存活状态。如果没有就可以初步判断主机没有在线或者使用了某些过滤设备过滤了 ICMP 的 REPLY。ICMP 全称 Internet Control Message Protocol,工作在
6、 OSI 的网络层。它的中文名为因特网控制报文协议。ICMP 报文要封装在 IP 数据报内部才能传输。其结构如(图 1)所示。ICMP 报文的格式如(图 2)所示。所有的 ICMP 报文的前 4 个字节都是一样的,但是其他字节互不相同。其中 0-7 位是类型字段,8-15 位是代码字段,16-31 位是校验和字段。校验和字段为 2 个字节,校验的范围是整个 ICMP 报文。本设计仅用到类型为 0 和 8 的 ICMP 报文,关于这两种类型报文的具体描述详见(图 3) 。20B图 1: ICMP 封装在 IP 内部IP 数据报IP 首部 ICMP 报文31(位 )15 167 8类型字段代码字段
7、校验和字段0(不同类型和代码有不同内容)图 2:ICMP 报文类型 代码 描述0 0 回应应答(Ping 应答,与类型 8 的 Ping 请求一起使用)8 0 回应请求(Ping 请求,与类型 8 的 Ping 应答一起使用)图 3:本设计使用的 ICMP 报文类型3 33.2 数据结构设计3.1.1IP 头部数据结构typedef struct iphdrunsigned int headlen:4; /ip头长度unsigned int wersion:4; /ip版本号unsigned char tos; /服务类型unsigned short totallen; /ip包总长度unsi
8、gned short id; /ip号unsigned short flag; /标记unsigned char ttl; /生存时间unsigned char prot; /协议(UDP TCP)unsigned short checksum; /校验和unsigned int sourceip; /源ipunsigned int destip; /目的ipIpHeader;3.1.2ICMP 头部数据结构typedef struct icmphdrBYTE type; /icmp类型码,回送请求的类型码为8BYTE code; /子类型码,保存与特定ICMP报文类型相关的细节信息USHOR
9、T checksum; /校验和USHORT id; /ICMP报文id 号USHORT seq; /ICMP数据报的序列号Icmpheader;4 43.3 系统流程图3.3.1主流程图 (图4)5 5图 43.3.2子流程图(图 5)6 6图 5四、详细设计 7 74.1.ICMP 报文分析ICMP 是一种差错和控制报文协议,用于传输错误报告和控制信息。ICMP报文分为头部和数据部分。ICMP 报文封装在 IP 数据报中传输。IP 报头中的类型为 1 时,表示报文的数据部分为 ICMP 报文。虽然 ICMP 报文由 IP 报文传输,但是并不能认为 ICMP 是 IP 的上层协议,而是 IP
10、 协议的有机补充。把 ICMP报文放在 IP 包中,是要利用 IP 的转发功能。类型(TYPE)是一个字节,表示 ICMP 消息的类型。代码(CODE)也是一个字节,表示报文类型的下一步信息。校验和共有两个字节,提供对整个ICMP 报文的校验和(和 IP 报文类型的进一步信息) 。校验和共两个字节,提供对整个 ICMP 报文的校验和。按照协议的功能来分,ICMP 报文可以分为1) ICMP 差错报文 包括目的不可达报告,超时报告,参数出错报告。2) ICMP 控制报文包括拥塞控制和源抑制报文,路游控制和重定向报文。3) ICMP 测试报文包括请求应答报文,时戳请求应答报文。本课程设计就是使用
11、ICMP 请求/应答报文来测试目的主机是否存在 ,请求者想某特定的主机发送请求,其中包含任选的数据。目的主机收到请求后,发送应答报文。在同一时刻,一台机器可以同时向多台主机发送请求报文。ICMP报文格式如图 6 所示,ICMP 回送报文格式如下图 7 所示。类型 代码 校验和标志位 序号任选数据类型 代码校 验 和数据区(变长)8 8图 6.ICMP 报文格式 图 7.ICMP 回应报文格式4.2.程序功能分析在初始化原始套接字之后,本程序就要开始在一个 IP 网段内寻找活动主机。因为要寻找活动的主机可能很多,为节省时间可以采用多线程编程。结合核心代码对程序的具体进行分析。4.2.1 使用原始
12、套接字 为了实现发送/监听 ICMP 抱文,必须使用原始套接字,创建原始套接字的代码如下:SOCKET sockraw;sockraw=WSASocket(AF_INET,SOCK_RAW,IPPROTO_ICMP,NULL,0,wsa_flag_overlapped);在 WSASocket 函数中,我们使用 IPPROTO_ICMP 表示接受 ICMP 数据包,为了使用发送接受超时设置(设置 SO_RCVTIMEO 或 SO_SNDTIMEO) ,必须将标志位置为 WSA_FLAG_OVERLAPPED。然后调用 setsockopt 函数设置读取迟延。在 setsockopt 函数中,s
13、ockraw 是之前创建的原始套接字,设置SOL_SOCKET 表明使用基本套接字处理 ICMP 抱文。设置 SO_RCVTIMEO 表示使用接受超时设置,SOSNDTIMEO 表示使用发送超时设置,在这里,超时时间均设置为 1000ms。4.2.2 定义 IP 头部和 ICMP 头部数据结构由于 socket 发送/捕获的是 IP 包,因此要分别定义 IP 头部的数据结构和ICMP 头部的数据结构。 IP 头部的数据结构和 ICMP 头部的数据结构在概要设计中已有分析。4.2.3 填充并发送请求类型的 ICMP 报文#define ICMP_ECHO 8 /请求回送#define DEF_P
14、ACKET_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数据头部9 9icmp_header *icmp_hdr;char *datapart;icmp_hdr=(icmpheader*)icmp_data;icm
15、p_hdr-type=icmp_echo; /设置类型icmp_hdr-id=(ushort)getcurrentthreadid(); /设置其 ID号为当前线程号datapart=icmp_data+sizeof(icmpheader); /计算出ICMP数据报的数据部分memset(datapart,A,datasize-sizeof(icmphearder); /填入数据((IcmpHeader*)icmp_data)-seq=0; /序列号((IcmpHeader* )icmp_data)-check_sum=0; /先将检验和置 0((IcmpHeader* )icmp_data)
16、-checksum=checksum(USHORT*) icmp_data,data_size);/Checksum 为计算校验和的函数,设校验和初值为 0,然后对数据每 16 位求异或,结果取反,便得校验和。其代码如下:unsinged long cksum=0;while (size1)cksum+=*buffer+;size-=sizeof(ushort);if(size)cksum+=*(uchar)buffer;cksum=(cksum16)+(cksumcksum+=(cksum16);return (ushort)(cksum);填充 ICMP 报文之后,应在 ICMP 报文之前
17、加上 IP 报头并发送出去。可调用下面的代码发送数据包。注意,这里的 dest 是填入目的主机的 IP 地址的一个sockaddr_in 数据结构,IP_STRING 是目的的主机的 IP 地址字符串。Struct sockaddr_in_dest;Dest.sin_family=AF_INET;Dest.sin_addr.s_addr=inet_addr(IP_STRING);Sendto(sockraw,icmp_data,datasize,0,(sockaddr*)4.2.4 解析数据包 如果所 ping 的目的主机存在,那么它会发出一个回送应答包。这是一个IP 包,受到后解析此数据包并
18、获得其中的 ICMP 信息。根据 IP 报头信息中的IP 报头长度字段,就可以得到 ICMP 报文的真实地址。ICMP 数据包中的 IP 地址就是活动主机的 IP。代码分析如下:#define ICMP_MIN 8#defineMAX_PING_PACKET_SIZE(MAX_PACKET+sizeof(IpHeader)char *recvbuf=newMAX_PING_PACKET_SIZE;struct sockaddr_in dest,from,end;int formlen=sizeof(from);int bytes=recvfrom(sockraw,recvbuf ,MAX_PA
19、CKET,0,(Struct sockaddr*)icmpheader *icmphdr;unsigned short iphdrlen;iphdr=(ipheader*)buf;iphdrlen=iphdr-headlen*4; /IP报头的长度icmphdr=(icmpheader *)(buf+iphdrlen); /跳过IP头/数据包太短 丢弃if(bytestype!=icmp_echo_reply) return; /ID不相符,丢弃if(icmphdr-id!=(USHORT)getcurrentthreadid() return; /输出正在使用的IP地址coutsin_add
20、r)endl;五、测试数据及其结果分析经调试,运行正常,运行结果如下图实验过程中的一些测试:(1) 在实验室运行程序时,发现某些主机无法发现。经分析,是因为这些主机装有瑞星防火墙,拒绝发送 ICMP 回送响应信息。如果将其防火墙关闭,或者修改规则,能正常发现。(2) 如果参数不符合,比如输入为:scanhost 10.0.,程序能够发现格式错11 11误,并给出警告并提示正确格式:输入格式错误:scanhost startip endip。(3) 在格式正确的情况下,如果 IP 地址格式有错误,程序不能正常发现。比如输入 scanhost 10.1 10.15 时,程序不能返回 IP 格式错误
21、的信息,反而给出发现主机 10.0.0.3 与 10.0.0.14。这说明程序对 IP 地址没有预先判断处理。(4) 经以上分析,程序容错性不是很好,能检查基本错误,但是一些问题(如 IP 格式检测)等没有处理好。(5) 还有,程序把能响应 ICMP 回送请求信息的主体都视为主机,这有一定的不科学性。比如上面截图中,10.0.0.3 是网关的 IP。但是程序未能将其和一般主机区分。六、调试过程中的问题1,找不到头文件。因为头文件存放位置错误。2,变量没有定义。因为变量没有定义和变量名书写写错。3,指针书写错误。4,宏参数列表错误。5,结构体指针传递错误。Cannot covert from s
22、truct iphdr * to struct icmphar * ipIpheader * iphdr.因为缺少成员运算符”.”。七、课程设计总结本次实验让我很好的理解了 ICMP 报文的结构,对 ICMP 协议也有了更好的认识。加深了对 ICMP 协议的理解,巩固了课堂知识,为以后学习网络协议打下基础。通过本次实验过程是我了解了 IP 协议的优点是简单,但缺少差错控制和查询机制,而网际控制报文协议(ICMP 具有补充 IP 功能的作用。在网络管理中,常常要确定当前网络在红处于活动状态的主机,这时可以通过ICMP 的回送和回送响应消息来完成这项工作。这课程设计的目的就是编制程序,利用 ICMP 数据包,发现网络中的活动主机,即 ping 消息的请求和应答。在调试过程中难免要出现一些问题,为了能够快速地确定错误的原因,12 12尽快的排除程序逻辑错误,通常把程序错误划分为三种类型:语法错误、运行错误和逻辑错误。在这次网络课程设计中,也发生了这样那样的错误,如变量没有定义、缺少头文件。出现问题是正常的,关键是如何去发现问题的根源,然后去解决它,通过查阅文献资料、请教老师和同学讨论、借助网络去解决,逐一对错误进行了调试,使程序基本能正常运行,大体上符合了设计的意图和设计的要求。