发现网络中的活动主机Word文档格式.docx
- 文档编号:21850668
- 上传时间:2023-02-01
- 格式:DOCX
- 页数:16
- 大小:105.81KB
发现网络中的活动主机Word文档格式.docx
《发现网络中的活动主机Word文档格式.docx》由会员分享,可在线阅读,更多相关《发现网络中的活动主机Word文档格式.docx(16页珍藏版)》请在冰豆网上搜索。
ICMP报文要封装在IP数据报部才能传输。
其结构如(图一)所示。
ICMP报文的格式如(图二)所示。
所有的ICMP报文的前4个字节都是一样的,但是其他字节互不相同。
其中0-7位是类型字段,8-15位是代码字段,16-31位是校验和字段。
校验和字段为2个字节,校验的围是整个ICMP报文。
本设计仅用到类型为0和8的ICMP报文,关于这两种类型报文的具体描述详见(图三)。
类型
代码
描述
回应应答(Ping应答,与类型8的Ping请求一起使用)
8
回应请求(Ping请求,与类型8的Ping应答一起使用)
图三:
本设计使用的ICMP报文类型
4.设计法:
本设计使用原始套接字生成ICMP报文来进行活动主机的探测。
设计的大体思想是把包类型设置为回送请求,将它发送给网络上的一个IP地址,如果这个IP地址已被占用,那么使用这个IP地址的主机上的TCP/IP软件就能够接收到这个ICMP回送请求,并返回一个ICMP回送响应信息。
由于接收到的回送响应ICMP包是封装在IP包,就需要解析该IP包,从中找到ICMP数据信息。
相反,如果这个IP地址没有人使用,那么发送的ICMP回送请求在设定的时延就不可能得到响应。
在初始化原始套接字后,程序就要开始在一个IP网段寻找活动主机。
由于在某网段需要发现的主机很多,为提高效率,采用了多线程编程。
主程序和子线程的流程图分别如(图四)和(图五)所示。
5.程序流程图:
6.程序清单:
#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;
7.实验步骤及测试
1.建立工程sy4
2.工程中添加文件名为“scanhost”的c++头文件
3.键入头文件scanhost.h文件的容
4.工程中添加文件名为“sy4”的c++源文件
5.键入sy4.cpp源文件的容
6.不断调试至程序正确
7.分别编译头文件和源文件
8.连接两个文件
8.在DOS下运行可执行文件“sy4.exe”
在DOS环境下发命令如下:
c:
\sy4\debug\sy4172.16.201.11172.16.201.18↙
其中sy4.exe是可执行文件。
后面的两个参数表示起始和结束IP地址。
程序执行后可从屏幕中看到所探测到的网段中活动主机的IP地址。
运行结果:
(测试了172.16.201.11到172.16.201.18网段,发现主机无误)
8.总结:
计算机网络是一门新兴的交叉学科,涉及计算机技术与通信技术两个学科。
网络技术经过多年发展,已经形成比较完善的体系。
而且,网络技术还在高速发展中,其应用广泛,知识更新飞快。
对于设计这样一个发展迅速的领域来说,我们课程设计的意义更加重大。
本课程设计主要提高了我两个面的能力:
1,真正理解和掌握处理网络问题的基本法;
2,培养了我在网络环境下的编程能力。
通过本次课程设计,我掌握了正确解读网络协议的一般法,懂得了使用C++实现协议并实现指定功能。
通过两个星期的辛勤劳动,我较好接受了网络问题处理的基本思路,掌握网络环境中编程的基本法。
这让我能够更好的接受前人的眼界成果,并在此基础上很好的接受新知识和继续学习,适应网络技术的飞快发展。
以上总结是宏观面的意义。
微观上,本次实验让我很好的理解了ICMP报文的结构,对ICMP协议也有了更好的认识。
实验过程中,我充分感受到了认真谨的重要性。
比如一次输入失误,把CreateThread写为CreateThead,虽然仅有一个r的差别,但是多花了一个多小时的调试时间。
这个意外也让我吸取了教训,编写程序的时候应该规,认真。
实验历时两,期间遇到了各类问题若干。
在此向给我帮助的老师和同学致以深深的意。
没有你们的帮忙,我不可能如此顺利的完成本设计。
9.参考资料:
[1]功宜;
计算机网络;
清华大学。
[2]功宜 晓英等编著;
计算机网络课程设计;
机械工业。
[3]揣锦华;
面向对象程序设计与VC++实践;
电子科技大学。
[4]高传善;
数据通信与计算机网络;
高等教育。
[5]互连网;
ICMP协议简介;
.opendigest.org/article.php/65。
[6]互连网;
透析ICMP协议;
WinSock网络编程实用宝典;
- 配套讲稿:
如PPT文件的首页显示word图标,表示该PPT已包含配套word讲稿。双击word图标可打开word文档。
- 特殊限制:
部分文档作品中含有的国旗、国徽等图片,仅作为作品整体效果示例展示,禁止商用。设计者仅对作品中独创性部分享有著作权。
- 关 键 词:
- 发现 网络 中的 活动 主机