[计算机]发现网络中的活动主机报告及源代码_第1页
[计算机]发现网络中的活动主机报告及源代码_第2页
[计算机]发现网络中的活动主机报告及源代码_第3页
[计算机]发现网络中的活动主机报告及源代码_第4页
[计算机]发现网络中的活动主机报告及源代码_第5页
已阅读5页,还剩20页未读 继续免费阅读

下载本文档

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

文档简介

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位类型字段代码字段校验和字段不同类型和代码有不同内容所有报文的前4个字节都

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

4、源主机被隔离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 信息请求已作废16 0 信息应答已作废17 0 地址掩码

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

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

7、OTO_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(sockRaw,SQL_socket,SO_S

8、NDTIMEO,(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 int headlen:4; /IP头

9、长度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 TCPnsigned short checksum; /校验和unsigned int sourceIP; /源IPunsigned int destIP; /目的IPIpHeader;/ICMP头部的数据结构typedef

10、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报文的填充代码如下:#define ICNP_ECHO 8 /请求回送#def

11、ine 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_hdr = (IcmpHeader*)icmp_d

12、ata;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; /先将校验和置0

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

14、= (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)

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

16、eader) char *recvbuf=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 sh

17、ort iphdrlen; Iphdr=(Ipheader *)buf; Iphdrlen = iphdr->headlen*4 ; /IP报头的长度 Icmphdr=(Icmpheader *)(buf+iphdrlen); /跳过IP报头 /数据包太短,丢弃 if(bytes<iphdrlen+ICMP_MIN) return; /不是回送响应Ping应答,丢弃 if(icmphdr->type !=ICMP_ECHO_REPLY) return; /Id号不相符,丢弃 if(icmphdr->id!=(USHOT)GetCurrentThreadId() retu

18、rn; /输出正在使用的IP地址。 Cout<<活动主机:<<inet_ntoa(from->sin_addr)<<endl;五程序流程图:一个用多线程实现的程序在第三局部中给出课程设计分析中的第三局部,以下分别是子程序流程图和主程序流程图程序见附录:1子程序流程图:开 始填充ICMP数据报发送数据报接收数报去掉IP报头,获取ICMP信息数据包太短? Y N不是回送响应? Y NID不符合? Y N输出数据报中的IP地址 结 束2主程序流程图:开 始将Start_IP添入到dest中起始IP地址Start_IP结束IP地址End_IP建立并初始化目的主

19、机的Sockaddr_in数据结构dest构造原始套接字,并初始化Start_IPEnd_IP? N Y Y线程数目太多?等待一定时间 N创立一个线程并执行Start_IP+ Y 还有线程在执行?等待一定时间 N结 束 六程序运行结果截图: 七课程设计心得:附录:参考文献源代码:#pragma pack(4)/#include "stdafx.h"#pragma comment (lib,"Ws2_32.lib")#define WIN32_LEAN_AND_MEAN#include <winsock2.h>#include <stdi

20、o.h>#include <stdlib.h>#include <iostream.h>#include <stdio.h>#include <sys/timeb.h>#include <time.h>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;un

21、signed char prot;unsigned short checksum;unsigned int sourceIP;unsigned int destIP;IpHeader;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#def

22、ine 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 from

23、len =sizeof(from);char *recvbuf=new charMAX_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),&w

24、saData)!=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;Ex

25、itProcess(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(

26、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_a

27、ddr.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)<=htonl(endIP)if(ThreadNumCounter>ThreadNumLimit)Sleep(5000);continue;DWORD ThreadID;sockaddr_in *pIPAddrTemp=new (sockaddr

28、_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(&

29、from,0,sizeof(from);startIP=htonl(htonl(startIP)+1);dest.sin_addr.s_addr=startIP;while(ThreadNumCounter!=0)Sleep(2000);return;cout<<"error"<<endl;void fill_icmp_data(char *icmp_data,int datasize)IcmpHeader *icmp_hdr;char *datapart;icmp_hdr=(IcmpHeader*)icmp_data;icmp_hdr->ty

30、pe=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;iphd

31、rlen=iphdr->headlen*4;icmphdr=(IcmpHeader *)(buf+iphdrlen);if(bytes<iphdrlen+ICMP_MIN)return;if(icmphdr->type!=ICMP_RCHO_REPLY)return;if(icmphdr->id!=(USHORT)GetCurrentThreadId()return;cout<<"活动主机: "<<endl;cout<<" "<<inet_ntoa(from->sin_addr

32、)<<endl;USHORT checksum(USHORT *buffer,int size)unsigned long cksum=0;while(size>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_dataMAX_PACKET;memset(icmp_data,0,MAX_PACKET);int datasize=DEF_PACKET_SIZE;datasize+=sizeof(IcmpHeader);fill_icmp_data(icmp_data,datasize);(Icmp

温馨提示

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

评论

0/150

提交评论