发现网络中的活动主机Word文档格式.docx
- 文档编号:5561588
- 上传时间:2023-05-05
- 格式:DOCX
- 页数:17
- 大小:97.67KB
发现网络中的活动主机Word文档格式.docx
《发现网络中的活动主机Word文档格式.docx》由会员分享,可在线阅读,更多相关《发现网络中的活动主机Word文档格式.docx(17页珍藏版)》请在冰点文库上搜索。
8
回应请求(Ping请求,与类型8的Ping应答一起使用)
图三:
本设计使用的ICMP报文类型
四.设计方法:
本设计使用原始套接字生成ICMP报文来进行活动主机的探测。
设计的大体思想是把包类型设置为回送请求,将它发送给网络上的一个IP地址,如果这个IP地址已被占用,那么使用这个IP地址的主机上的TCP/IP软件就能够接收到这个ICMP回送请求,并返回一个ICMP回送响应信息。
由于接收到的回送响应ICMP包是封装在IP包内,就需要解析该IP包,从中找到ICMP数据信息。
相反,如果这个IP地址没有人使用,那么发送的ICMP回送请求在设定的时延内就不可能得到响应。
在初始化原始套接字后,程序就要开始在一个IP网段内寻找活动主机。
由于在某网段内需要发现的主机很多,为提高效率,采用了多线程编程。
主程序和子线程的流程图分别如(图四)和(图五)所示。
五.程序流程图:
六.程序清单:
#pragmapack(4)
#pragmacomment(lib,"
WS2_32.LIB"
#defineWIN32_LEAN_AND_MEAN
#include<
winsock2.h>
stdio.h>
winsock.h>
iostream.h>
sys/timeb.h>
time.h>
winbase.h>
//头文件
typedefstructiphdr{//IP头
unsignedintheadlen:
4;
//IP头长度
unsignedintversion:
//IP版本号
unsignedchartos;
//服务类型
unsignedshortid;
//ID号
unsignedshortflag;
//标记
unsignedcharttl;
//生存时间
unsignedcharprot;
//协议
unsignedshortchecksum;
//效验和
unsignedintsourceIP;
//源IP
unsignedintdestIP;
//目的IP
}IpHeader;
//IP头部
typedefstructicmphdr{//ICMP头
BYTEtype;
//ICMP类型码
BYTEcode;
//子类型码
USHORTchecksum;
USHORTid;
USHORTseq;
//ICMP数据报的序列号
}IcmpHeader;
//ICMP包头部
#defineICMP_ECHO8//请求回送
#defineICMP_ECHO_REPLY0//请求回应
#defineICMP_MIN8//ICMP包头长度(最小ICMP包长度)
#defineSTATUS_FAILED0xFFFF//错误码
#defineDEF_PACKET_SIZE32//缺省数据块长度
#defineMAX_PACKET1024//最大数据块长度
#defineMAX_PING_PACKET_SIZE(MAX_PACKET+sizeof(IpHeader))
//最大接收数据包长度
voidfill_icmp_data(char*,int);
USHORTchecksum(USHORT*,int);
voiddecode_resp(char*,int,structsockaddr_in*);
DWORDWINAPIFindIP(LPVOIDpIPAddrTemp);
//函数的申明
WSADATAwsaData;
SOCKETsockRaw;
//原始套接字
structsockaddr_indest,from,end;
//dest:
搜索目的IP,
//from:
接收ICMP包的源IP
//end:
搜索终止IP。
intfromlen=sizeof(from);
//接收ICMP包长度
char*recvbuf=newchar[MAX_PING_PACKET_SIZE];
//接受ICMP包缓冲区
unsignedintaddr=0;
//IP地址
longThreadNumCounter=0,ThreadNumLimit=20;
//线程数及最大允许线程数
long*aa=&
ThreadNumCounter;
//全局变量的申明
voidmain(intargc,char*argv[])
{
if(argc!
=3)//判断格式是否正确
{
cout<
<
"
输入格式错误:
scanhoststart_ipend_ip"
endl;
return;
}
if(WSAStartup(MAKEWORD(2,1),&
wsaData)!
=0)
WSAStartupfailed:
GetLastError()<
ExitProcess(STATUS_FAILED);
//创建原始套接字
sockRaw=WSASocket(AF_INET,SOCK_RAW,IPPROTO_ICMP,NULL,0,WSA_FLAG_OVERLAPPED);
if(sockRaw==INVALID_SOCKET)
WSASocket()failed:
WSAGetLastError()<
inttimeout=1000;
intbread=setsockopt(sockRaw,SOL_SOCKET,SO_RCVTIMEO,(char*)&
timeout,sizeof(timeout));
if(bread==SOCKET_ERROR)
failedtosetrecvtimeou:
timeout=1000;
bread=setsockopt(sockRaw,SOL_SOCKET,SO_SNDTIMEO,(char*)&
failedtosetsendtimeout:
memset(&
dest,0,sizeof(dest));
//初始化dest结构
unsignedlongstartIP,endIP;
dest.sin_family=AF_INET;
dest.sin_addr.s_addr=inet_addr(argv[1]);
//填入开始搜索IP
startIP=inet_addr(argv[1]);
end.sin_family=AF_INET;
end.sin_addr.s_addr=inet_addr(argv[2]);
endIP=inet_addr(argv[2]);
//填入结束搜索IP地址
HANDLEhThread;
while(htonl(startIP)<
=htonl(endIP))//起始IP比结束IP小
if(ThreadNumCounter>
ThreadNumLimit)//判断线程数目,如果太多,休眠
{
Sleep(5000);
continue;
}
DWORDThreadID;
sockaddr_in*pIPAddrTemp=new(sockaddr_in);
if(!
pIPAddrTemp)
cout<
memoryallocfailed"
return;
*pIPAddrTemp=dest;
clock_tstart;
start=clock();
hThread=CreateThread(NULL,NULL,FindIP,(LPVOID)pIPAddrTemp,NULL,&
ThreadID);
longi=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!
Sleep(2000);
}
voidfill_icmp_data(char*icmp_data,intdatasize)
IcmpHeader*icmp_hdr;
char*datapart;
icmp_hdr=(IcmpHeader*)icmp_data;
icmp_hdr->
type=ICMP_ECHO;
//设置类型信息
id=(USHORT)GetCurrentThreadId();
//设置其ID号为当前线程ID号
datapart=icmp_data+sizeof(IcmpHeader);
//计算ICMP数据报的数据部分
memset(datapart,'
A'
datasize-sizeof(IcmpHeader));
//填入数据
//ICMP数据包的填充
voiddecode_resp(char*buf,intbytes,structsockaddr_in*from)
IpHeader*iphdr;
IcmpHeader*icmphdr;
unsignedshortiphdrlen;
iphdr=(IpHeader*)buf;
iphdrlen=iphdr->
headlen*4;
icmphdr=(IcmpHeader*)(buf+iphdrlen);
if(bytes<
iphdrlen+ICMP_MIN)return;
if(icmphdr->
type!
=ICMP_ECHO_REPLY)return;
id!
=(USHORT)GetCurrentThreadId())return;
cout<
inet_ntoa(from->
sin_addr)<
//返回包的解析,以及输出
USHORTchecksum(USHORT*buffer,intsize)
unsignedlongcksum=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);
//效验和的计算
DWORDWINAPIFindIP(LPVOIDpIPAddrTemp)
InterlockedIncrement(aa);
//线程数目+1
charicmp_data[MAX_PACKET];
memset(icmp_data,0,MAX_PACKET);
//数据报初始化
intdatasize=DEF_PACKET_SIZE;
//数据报报文的缺省长度
datasize+=sizeof(IcmpHeader);
//加上icmp头部长度
fill_icmp_data(icmp_data,datasize);
//填充包
((IcmpHeader*)icmp_data)->
checksum=0;
//效验和置零
seq=0;
//序列号置零
checksum=checksum((USHORT*)icmp_data,datasize);
//计算效验和后填人
Intbwrote=sendto(sockRaw,icmp_data,datasize,0,(structsockaddr*)pIPAddrTemp,sizeof(dest));
//发送数据报
intn=0;
if(bwrote==SOCKET_ERROR)
if(WSAGetLastError()==WSAETIMEDOUT)
timedout"
sendtofailed:
n=1;
if(WSAGetLastError()==WSAETIMEDOUT)
if(bwrote<
datasize)
Wrote"
bwrote<
bytes"
intbread=recvfrom(sockRaw,recvbuf,MAX_PING_PACKET_SIZE,0,(structsockaddr*)&
from,&
fromlen);
//数据包的接收
if(WSAGetLastError()==WSAETIMEDOUT)
recvfromfailed:
if(n==0)
decode_resp(recvbuf,bread,&
from);
InterlockedDecrement(aa);
return0;
//子线程的编写
七.测试数据及其结果:
运行结果:
(测试了10.0.01~10.0.0.255和10.0.0.10~10.0.0.50两个网段,发现主机无误)
实验过程中的一些测试:
(1)在实验室运行程序时,发现某些主机无法发现。
经分析,是因为这些主机装有瑞星防火墙,拒绝发送ICMP回送响应信息。
如果将其防火墙关闭,或者修改规则,能正常发现。
(2)如果参数不符合,比如输入为:
scanhost10.0.,程序能够发现格式错误,并给出警告并提示正确格式:
scanhoststartipendip。
(3)在格式正确的情况下,如果IP地址格式有错误,程序不能正常发现。
比如输入scanhost10.110.15时,程序不能返回IP格式错误的信息,反而给出发现主机10.0.0.3与10.0.0.14。
这说明程序对IP地址没有预先判断处理。
(4)经以上分析,程序容错性不是很好,能检查基本错误,但是一些问题(如IP格式检测)等没有处理好。
(5)还有,程序把能响应ICMP回送请求信息的主体都视为主机,这有一定的不科学性。
比如上面截图中,10.0.0.3是网关的IP。
但是程序未能将其和一般主机区分。
八.总结:
计算机网络是一门新兴的交叉学科,涉及计算机技术与通信技术两个学科。
网络技术经过多年发展,已经形成比较完善的体系。
而且,网络技术还在高速发展中,其应用广泛,知识更新飞快。
对于设计这样一个发展迅速的领域来说,我们课程设计的意义更加重大。
本课程设计主要提高了我两个方面的能力:
1,真正理解和掌握处理网络问题的基本方法;
2,培养了我在网络环境下的编程能力。
通过本次课程设计,我掌握了正确解读网络协议的一般方法,懂得了使用C++实现协议并实现指定功能。
通过两个星期的辛勤劳动,我较好接受了网络问题处理的基本思路,掌握网络环境中编程的基本方法。
这让我能够更好的接受前人的眼界成果,并在此基础上很好的接受新知识和继续学习,适应网络技术的飞快发展。
以上总结是宏观方面的意义。
微观上,本次实验让我很好的理解了ICMP报文的结构,对ICMP协议也有了更好的认识。
实验过程中,我充分感受到了认真严谨的重要性。
比如一次输入失误,把CreateThread写为CreateThead,虽然仅有一个r的差别,但是多花了一个多小时的调试时间。
这个意外也让我吸取了教训,编写程序的时候应该规范,认真。
实验历时两周,期间遇到了各类问题若干。
在此向给我帮助的老师和同学致以深深的谢意。
没有你们的帮忙,我不可能如此顺利的完成本设计。
九.参考资料:
[1]吴功宜;
计算机网络;
清华大学出版社。
[2]吴功宜 胡晓英等编著;
计算机网络课程设计;
机械工业出版社。
[3]揣锦华;
面向对象程序设计与VC++实践;
西安电子科技大学出版社。
[4]高传善;
数据通信与计算机网络;
高等教育出版社。
[5]互连网;
ICMP协议简介;
http:
//www.opendigest.org/article.php/65。
[6]互连网;
透析ICMP协议;
WinSock网络编程实用宝典;
- 配套讲稿:
如PPT文件的首页显示word图标,表示该PPT已包含配套word讲稿。双击word图标可打开word文档。
- 特殊限制:
部分文档作品中含有的国旗、国徽等图片,仅作为作品整体效果示例展示,禁止商用。设计者仅对作品中独创性部分享有著作权。
- 关 键 词:
- 发现 网络 中的 活动 主机