《计算机网络》第十章_第1页
《计算机网络》第十章_第2页
《计算机网络》第十章_第3页
《计算机网络》第十章_第4页
《计算机网络》第十章_第5页
已阅读5页,还剩11页未读 继续免费阅读

下载本文档

版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领

文档简介

1、计算机网络课程设计报告题 目: 发现网络中的活动主机 学生姓名: 刘 枫 学 号: 201217010148 专业班级: 计算机科学与技术12101班 同组姓名: 指导教师: 聂方彦 设计时间: 2015年上学期第17周 指导老师意见:评定成绩: 签名: 日期:2015年7月3日一、程设计的目的和意义 IP协议的优点是简洁,但缺少差错控制和查询机制,而网际控制报文协议(ICMP)具有补充IP功能的作用。在网络管理中,常常要确定当前网络中处于活动状态的主机,这时可以通过使用ICMP的回送和回送响应消息来完成这项工作。本课程设计的目的就是编制程序,利用ICMP数据包,发现指定网段中的活动主机。通过

2、课程设计,使学生更加熟悉ICMP报文的结构,对ICMP协议有更好的理解和认识。二、程设计的内容和要求 设计程序,其功能是发送ICMP数据包,以获取指定网段中的活动主机,并将结果显示在标准输出上。 程序的具体要求如下:1) 用命令行形式运行: scanhost Start_adress End_adress其中scanhost为程序名;Start_adress为被搜索网段的开始IP地址;End_adress为被搜索网段的结束IP地址。2)输出格式为: 活动主机1 活动主机2三、课程设计的相关技术 编制程序前首先要对ICMP报文的格式有一定的了解,ICMP报文是在IP数据报内部传输的,其结构如图1

3、所示。图1 ICMP封装在IP内部ICMP报文的格式如图2所示。所有报文的前4个字节都是一样的,但是其它字节则互不相同。其中类型字段可以有15个不同的值,以描述特定类型的ICMP报文,某些ICMP报文还使用代码字段的值来进一步描述不用的条件。按验和字段为2字节,校验的范围是整个ICMP报文。检验和是必须的,其计算方法与IP协议头部校验和的计算方法一样。0 7 8 15 16 31(位)类型字段代码字段校验和字段(不同类型和代码有不同内容)图2 ICMP报文各种类型的ICMP报文如图3所示(ICMP报文类型),不同类型由报文中的类型字段和代码字段来共同决定。本课程设计的目的是发现网络中的活动主机

4、,就是使用ICMP的回送和回送响应消息发现网络中的活动主机,即Ping消息的请求和应答。那幺,发送的ICMP的数据包类型设置为回送请求(类型号为8)。四、课程设计过程本程序使用原始套接字生成ICMP报文来进行活动主机的探查。这个程序使用的是回送请求与应答消息。程序的大致思想是把ICMP的数据包类型设置为回送请求,将它发送给网络上的一个IP地址,如果这个IP地址已经被占用的话,那幺使用位于这个IP地址的主机上的TCP/IP软件就能够接收到这个ICMP回送请求,从而返回一个ICMP回送响应(类型号为0)信息。信息封装在一个IP包中,我们需要解析该IP包,从中找到ICMP数据信息。相反,如果这个IP

5、地址没有人使用,那幺发送的ICMP回送请求在设定的延时内就不可能得到响应。在初始化原始套接字之后,本程序就要开始在一个IP网段内寻找活动主机。因为要寻找的主机可能很多,为节省时间可以采用多线程编程。下面接结合核心代码对程序的具体实现进行讲解,同时为使程序流程更加清晰,去掉了错误检查等保护性代码。4.1、使用原始套接字为了实现发送/监听ICMP报文,必须使用原始套接字,创建原始套接字的代码如下:socket sockRaw;sockRaw=SAocket(AF_INET,sock_Raw,IPPROTO_ICMP,NULL,0,WSA_FLAG_OVERLAPPED); 在WSASocket函数

6、中,我们使用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(sockRaw,SQL_socket,SO_SNDTIMEO,(char*)&timeout,sizeof(timeout);类 型 代 码

7、描 述 0 0 回送响应(PING应答)3 目的不可达0 网络不可达1 主机不可达2 协议不可达3 端口不可达4 需要进行分片但设置了禁止分片比特5 源主机选择路由失败6 无法识别目的网络7 无法识别目的主机8 源主机被隔离9 目的网络被禁止10 目的主机被禁止11 由于服务类型(TOS),网络不可达12 由于服务类型(TOS),主机不可达13 由于过滤,通信被强行禁止14 主机越权15 优先权终止生效 4 0 源端被关闭(基本流控制)5 重定向0 对网络重定向1 对主机重定向2 对服务类型和网络重定向3 对服务类型和主机重定向 8 0 回送请求(PING请求)9 0 路由器通告10 0 路由

8、器请求11 超时0 传输期间生存期减为01 数据报组装期间生存期减为012 参数问题0 各种IP头部错误1 缺少必须的选项13 0 时间戳请求14 0 时间戳应答15 0 信息请求(已作废)16 0 信息应答(已作废)17 0 地址掩码请求18 0 地址掩码应答图3 ICMP报文类型 在setsockopt函数中,sockRaw是之前创建的原始套接字,设置SQL_SOCKET表明使用基本套接字处理ICMP报文。设置SO_RCVTIMEO表示使用接收超时设置,SO_SNDTIMEO表示使用发送超时设置,在这里,超时时间均设置为1000ms。 4.2、定义IP头部和ICMP头部的数据结构由于soc

9、ket发送/捕获的是IP包,因此要分别定义IP头部的数据结构ICMP头部数据结构。4.3、填充并发送回送请求类型的ICMP报文为了使收到数据包的目的主机发送响应,我们需要向目的主机发送回送请求类型的ICMP报文。从图3中可知,回送请求的类型号为8。因此ICMP报文的填充代码如下:checksum为校验和的函数,设校验和初值为0 ,然后对数据每16为求异或,结果取反,便得校验和。其代码如下: USHORT checksum(USHORT *buffer, int size) unsigned long cksum = 0; while(size>1) cksum+=*buffer+; si

10、ze -=sizeof(USHORT);if(size)cksum +=*(UCHAR*)buffer;cksum = (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_fami

11、ly = AF_INET; dest.sin_addr.s_addr = inet_addr(IP_STRING); /填入搜索的IP地址 sendto(sockRaw,icmp_data,datasize,0,(sockaddr*)&dest,sizeof(dest);4.4、解析数据包如果所Ping的目的主机所在,那么它会发送一个回送应答包。这是一个IP包,收到后解析此数据包并获取其中的ICMP信息。根据IP报头信息中的IP报头长度字段,就可以得到ICMP报文的真实地址。ICMP数据包中的IP地址就是活动主机的IP。代码如下:4.5、程序流程图一个用多线程实现的程序在课程设计过程的

12、第三部分中给出,以下分别是主程序流程图和子程序流程图:开 始将Start_IP添入到dest中起始IP地址Start_IP结束IP地址End_IP建立并初始化目的主机的Sockaddr_in数据结构dest构造原始套接字,并初始化Start_IPEnd_IP? N Y Y线程数目太多?等待一定时间 N创建一个线程并执行Start_IP+ Y 还有线程在执行?等待一定时间 N结 束 图4 主程序流程图开 始填充ICMP数据报发送数据报接收数报去掉IP报头,获取ICMP信息数据包太短? Y N不是回送响应? Y NID不符合? Y N输出数据报中的IP地址 结 束图5 子程序流程图五、程序运行结果

13、六、课程设计小结通过此次课程设计,我加深了对ICMP协议的理解,巩固了课堂知识。由于网络协议比较抽象、难学,自己学得也不够深入,加上还要把所学知识运用到实践中来,所以一开始时感觉比较困难,而且在调试过程中难免要出现一些如变量没有定义、缺少头文件、大小写错误以及其它问题,通过查阅文献资料、向同学请教以及认真地思考与分析,逐一对错误进行了调试,才使得程序能正常运行,大体上符合了设计的目的和要求。在程序的调试过程中,出现问题是正常的,关键是如何去发现问题的根源,然后去解决它。为了能够快速地确定错误的原因,尽快的排除程序错误,通常把程序错误划分为三种类型:语法错误、运行错误和逻辑错误。在设计过程中,我

14、们可以先找出问题,看是属于哪一类错误,然后再将问题一一解决,这样既解决了疑难问题又节省了不少时间。参考文献1 吴功宜, 胡晓英, 张仁, 何云, 王宁编著. 计算机网络课程设计M. 北京:机械工业出版社, 2014.82 谢希仁著. 计算机网络(第六版). 北京.电子工业出版社, 2013.63 陈坚, 陈伟. Visual C+网络高级编程M. 北京: 人民邮电出版社,2012.64 陈鸣等. 计算机网络实验教程,从原理到实践. 北京: 机械工业出版社,20075 吴功宜,等. 计算机网络高级教程M. 北京: 清华大学出版社,2007.66 吴功宜,等. 计算机网络高级软件编程技术M. 北京

15、: 清华大学出版社,2008.67 吴功宜,等. 网络安全高级软件编程技术M. 北京: 清华大学出版社,20010.6附录:源代码#include <winsock2.h>#include <iostream.h>#include <time.h>#pragma comment (lib,"Ws2_32.lib")/IP包头部结构typedef struct iphdrunsigned int headlen:4;/头部长度unsigned int version:4;/版本号unsigned char tos;/服务类型unsigned

16、 short totallen;/总长度unsigned short id;/IP包ID号unsigned short falg;/标记unsigned char ttl;/生存时间unsigned char prot;/协议类型unsigned short checksum;/校验和unsigned int sourceIP;/源IP地址unsigned int destIP;/目的IP地址IpHeader;/ICMP包头布结构typedef struct icmphdrBYTE type;BYTE code;USHORT checksum;USHORT id;USHORT seg;Icmp

17、Header;#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_data(char *,int);USHORT checksum(USHORT *,int);void decode_resp(char *,int,struct so

18、ckaddr_in *);DWORD WINAPI FindIP(LPVOID pIPAddrTemp);WSADATA wsaData;SOCKET sockRaw;/原始套接字struct sockaddr_in dest,from,end;int fromlen =sizeof(from);/接收ICMP包长度char *recvbuf=new charMAX_PING_PACKET_SIZE;unsigned int addr=0;long ThreadNumCounter=0,ThreadNumLimit=20;long *aa=&ThreadNumCounter;/填充IC

19、MP包的函数void fill_icmp_data(char *icmp_data,int datasize)IcmpHeader *icmp_hdr;char *datapart;icmp_hdr=(IcmpHeader*)icmp_data;icmp_hdr->type=ICMP_RCHO;/设置类型信息icmp_hdr->id=(USHORT)GetCurrentThreadId();/设置当前线程IDdatapart=icmp_data+sizeof(IcmpHeader);/计算ICMP包数据部分memset(datapart,'A',datasize-s

20、izeof(IcmpHeader);/解析IP地址的函数void decode_resp(char *buf,int bytes,struct sockaddr_in *from)IpHeader *iphdr;IcmpHeader *icmphdr;unsigned short iphdrlen;iphdr=(IpHeader*) buf;/跳过IP包头部iphdrlen=iphdr->headlen*4;icmphdr=(IcmpHeader *)(buf+iphdrlen);/数据包太短,跳过if(bytes<iphdrlen+ICMP_MIN)return;/不是回送响应,

21、丢弃if(icmphdr->type!=ICMP_RCHO_REPLY)return;/ID不符if(icmphdr->id!=(USHORT)GetCurrentThreadId()return;cout<<"活动主机: "<<inet_ntoa(from->sin_addr)<<endl;/校验和计算函数USHORT checksum(USHORT *buffer,int size)unsigned long cksum=0;while(size>1)cksum+=*buffer+;size-=sizeof(U

22、SHORT);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_dataMAX_PACKET;memset(icmp_data,0,MAX_PACKET);int datasize=DEF_PACKET_SIZE;datasize+=size

23、of(IcmpHeader);/填充ICMP包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);/发送ICMP包int bwrote=sendto(sockRaw,icmp_data,datasize,0,(struct sockaddr *)pIPAddrTemp,

24、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"&l

25、t;<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)i

26、f(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;void main(int argc,char *argv)/检查输入

27、命令格式if(argc!=3)cout<<"输入格式错误: 996 start_adress end_adress"<<endl;return;/开始使用Ws2_32.dllif(WSAStartup(MAKEWORD(2,1),&wsaData)!=0)cout<<"WASStartup failed"<<GetLastError()<<endl;ExitProcess(STATUS_FAILED);/创建原始套接字sockRaw=WSASocket(AF_INET,SOCK_RAW,

28、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 TIMEOU

温馨提示

  • 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
  • 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
  • 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
  • 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
  • 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
  • 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
  • 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。

评论

0/150

提交评论