东北大学秦皇岛分校网络课程设计.docx
- 文档编号:30020957
- 上传时间:2023-08-04
- 格式:DOCX
- 页数:17
- 大小:230.08KB
东北大学秦皇岛分校网络课程设计.docx
《东北大学秦皇岛分校网络课程设计.docx》由会员分享,可在线阅读,更多相关《东北大学秦皇岛分校网络课程设计.docx(17页珍藏版)》请在冰豆网上搜索。
东北大学秦皇岛分校网络课程设计
利用WinPcap编程获取IP地址与MAC地址的对应关系
院别
计算机与通信工程学院
专业名称
计算机科学与技术
班级学号
学生姓名
成绩
2013年7月5日
目录
第一部分需求分析
第二部分详细设计
第三部分调试分析
第四部分测试结果
第五部分附录(源代码)
第六部分总结
第七部分参考文献
一、需求分析
学会安装WinPcap,熟悉WinPcap编程机制,熟悉ARP协议,学会在VC的IDE中添加相应的库文件,掌握Windows下应用程序的消息机制,利用WinPcap实现ARP协议,从而获取以太网上任意一台主机的IP地址与MAC地址的对应关系。
通过编制程序,获取网络中的ARP数据包,解析数据包的内容,将结果显示在标准输出上,并同时写入日志文件。
要求显示mac地址和ip地址的对应关系,通过发送arp请求数据帧和接收arp相应数据帧的工作,对收到的arp相应数据帧进行分析,获得目的主机的ip地址和对应的mac地址,将ip地址和mac地址显示出来。
二、详细设计
1、Winpcap的安装
Winpcap功能强大,效率高,使用方便,但是,使用前的准备工作要费一番功夫,步骤如下:
步骤1:
安装驱动程序。
下载WinPcapDriver和DLL并安装,安装后重启机器。
步骤2:
下载wpdpack(Developer’spack)。
解压后会看到其中包含了docs、Include、lib、Examples等文件夹。
步骤3:
在VC中设定Include目录及Library目录。
具体做法:
打开VC后,Tools->Option->Directories,在includefiles中添加……\wpdpack\Include目录(步骤2中得到的);在Libraryfiles中添加……\wpdpack\Lib目录。
2、arp相关知识
(1)arp数据报的消息格式
网络上的每台主机或设备都有一个或多个IP地址。
IP地址是网络层的地址,在网络层,数据被组装成IP包。
但是发送IP包需要物理设备的支持(通常是Ethernet设备,在本课程设计中我们指定为Ethernet设备),即发送端必须知道目的物理地址才能将IP包发送出去,所以需要一种将IP地址映射为物理地址的机制。
ARP协议就是用来完成这个任务的。
ARP协议能够在同一个物理网络中,在给定目的主机或设备的IP地址的条件下,得到目的主机或设备的物理地址。
ARP协议的数据包格式如图1所示:
08162431(位)
硬件类型
协议类型
物理地址长度
协议地址长度
操作
源物理地址(八位组0~3)
源物理地址(八位组4~5)
源IP地址(八位组0~1)
源IP地址(八位组2~3)
目的物理地址(八位组0~1)
目的物理地址(八位组2~5)
目的IP地址(八位组0~3)
图1arp数据报消息格式
硬件类型:
指定硬件接口类型。
例如,值为1表示Ethernet
协议类型:
指定发送方支持的上层协议的类型
物理地址长度:
指定物理(硬件)地址的长度
协议地址长度:
网络层协议的地址长度。
若为IP协议,其值为4
操作:
指定ARP的操作类型,例如,1表示ARP请求,2表示ARP应答
源物理地址:
指定发送方的IP地址
目的物理地址:
指定目的物理地址。
目的IP地址:
指定目的IP地址
ARP分组必须在数据链路层中被封装成侦,才能发送出去封装形式如图2所示
图2将ARP数据包封装成一个帧
(2)arp协议的工作流程
①在发送一个ARP分组之前,源主机首先根据目的IP地址,在本地ARP高速缓存表中查找与之对应的目的物理地址。
如果找到对应的物理地址,就不用进行地址解析,否则需要进行地址解析。
②实现地址解析的第一步是产生ARP请求分组。
在相应的字段写入本地主机的源物理地址、源IP地址,在目的物理地址字段写入0,并在操作字段写入1。
③将ARP分组发送到本地的数据链路层,并封装成帧。
以源物理地址作为源地址,以物理广播地址(FF-FF-FF-FF-FF-FF)作为目的地址,通过物理层发送出去。
④由于采用了广播地址,因此网段内所有的主机或设备都能接受到该帧。
除了目的主机外,所有接受到该分组的主机和设备都会丢弃该分组,因为目的主机能够识别ARP消息中的目的IP地址。
⑤目的主机发送ARP应答分组。
在ARP应答分组中,以请求分组中源物理地址、源IP地址作为其目的物理地址、目的IP地址,并将目的主机自身的物理地址、IP地址填入应答分组的源物理地址、源IP地址字段,并在操作字段中写入2。
该分组通过数据链路层以点对点的方式发送出去(因为现在目的方已经知道双方的物理地址)。
⑥源结点接收到ARP应答分组,知道对应于目的IP地址的目的物理地址,将它作为一条新记录加入到ARP高速缓存表。
⑦源结点将有完整源IP地址、源物理地址、目的IP地址、目的物理地址的信息和数据作为一个发送分组,传送给它的数据链路层并封装成桢,然后以点对点的方式发送到目的主机。
3、程序的数据结构分析
structARPPKT
{
unsignedshorthdType;//硬件类型,0001位ethernet
unsignedshortprotocolType;//协议类型,0800表示上层协议为ip
unsignedcharhdSize;//硬件地址长度,值为6
unsignedcharprotocolSize;//协议地址长度,值为4
unsignedshortop;//操作值,0001/0002分别表示arp请求/应答
unsignedcharsrcMAC[6];//源mac地址
unsignedcharsrcIP[4];//源ip地址
unsignedchardstMAC[6];//目标mac地址
unsignedchardstIP[4];//目标ip地址
};
上述结构体定义的是arp消息头的格式,里面定义了arp消息头需要的字段。
4、程序中算法分析
(1)winpcap编程机制
①程序中会用到Winpcap,Winpcap是Win32环境下数据包捕获的开放代码函数库。
基于Winpcap的应用程序一般按照下面几个步骤进行设计:
●输出网卡设备列表。
●选择网卡并打开。
●捕获数据包时,可能需要设置过滤器。
●捕获数据包或者发送数据包。
②在程序设计过程中需要注意网络—主机字节顺序的转化。
由于不同的计算机系统所采用的数据表示方式不同,对于2B或4B的数据,有的采用低字节地址存放数据的高权值位,而有的却以低地址字节存放数据低权位值,在网络的数据传输中,我们应该统一表示,所以我们在捕获数据包后,应将数据包头部的表示长度或类型的数据转换成本地机的表达形式。
可以利用函数ntohs()将网络字节序转换为主机字节序。
③选择网卡并打开时,注意选择可用的网卡。
(2)程序的执行过程如下:
①取得当前网卡设备列表。
②选择Ethernet网卡并打开,注意判断所选网卡是否为实际存在的可用网卡。
③设置过滤器,此处的过滤器正则表达式为“arp”或者“etherproto\\arp”。
④捕获数据包并进行处理(包括输出各IP地址,物理地址,操作类型以及时间)。
由于要记录日志文件,为了便于输出流参数,建议采用pcap_next_ex()函数。
流程图如图3所示:
图3流程图
5、程序中的操作
获取网络设备列表,并以混杂模式打开网络设备
//获取网络设备列表
if(pcap_findalldevs(&alldevs,errbuf)==-1)
{
cout<<"Errorinpcap_findalldevs:
"< return; } //选择Ethernet卡 for(d=alldevs;d;d=d->next) { //以混杂模式打开网卡,以接受所有的帧 if((adhandle=pcap_open_live(d->name,1000,1,300,errbuf))==NULL) { cout<<"\nUnabletoopentheadapter."; pcap_freealldevs(alldevs);//释放设备列表 return; } if(pcap_datalink(adhandle)==DLT_EN10MB&&d->addresses! =NULL) break; } 编译过滤器并设置过滤器,只捕获ARP数据包 charpacket_filter[]=”etherproto\\arp”;//过滤,选择arp协议 if(pcap_compile(adhandle,&fcode,packet_filter,1,netmask)<0) {cout<<"\nUnabletocompilethepacketfilter.Checkthesyntax.\n"; pcap_freealldevs(alldevs); return; } //设置过滤器 if(pcap_setfilter(adhandle,&fcode)<0) {cout<<"\nErrorsettingthefilter.\n"; pcap_freealldevs(alldevs); return; } 循环捕获ARP包,并进行解析 while((result=pcap_next_ex(adhandle,&header,&pkt_data))>=0) { 输出ARP数据包的各个域的内容到文件和屏幕上 } 三、调试分析 在程序调试过程中会遇到各种的麻烦,不是这里错了就是那里错了,在调试程序过程中遇到了好多头文件的问题,都是打不开一些头文件,原因就是因为在安装winpcap时vc++6.0包含wpdpack文件夹中的include文件夹失败,还会遇到这样的错误“errorC2144: syntaxerror: missing';'beforetype'unsignedint'”,它的解决方法可以在程序的开头添加“#define_W64”就可以解决这个错误。 四、测试结果 程序的运行结果如下: op=1表示的是发送的是请求包,op=2表示的是发送的是响应包。 五、附录(源代码) #define_W64 #include #include #include #include #include #include #include #include"strsafe.h" #include usingnamespacestd; #pragmacomment(lib,"ws2_32.lib") #pragmacomment(lib,"wpcap.lib") structARPPKT { unsignedshorthdType;//硬件类型,0001位ethernet unsignedshortprotocolType;//协议类型,0800表示上层协议为ip unsignedcharhdSize;//硬件地址长度,值为6 unsignedcharprotocolSize;//协议地址长度,值为4 unsignedshortop;//操作值,0001/0002分别表示arp请求/应答 unsignedcharsrcMAC[6];//源mac地址 unsignedcharsrcIP[4];//源ip地址 unsignedchardstMAC[6];//目标mac地址 unsignedchardstIP[4];//目标ip地址 }; pcap_if_t*allDevs; pcap_if_t*pt; pcap_t*fp; charerrMsgBuffer[PCAP_ERRBUF_SIZE]; unsignedintnetMask; charpacketFilter[]="arp"; bpf_programfcode; pcap_pkthdr*header; constunsignedchar*pktData; voidpacketHandler(constpcap_pkthdr*hdr,constunsignedchar*pkt_data,ostream&out); voidInitAdapter(); intmain(intagrc,char**agrv) { if(pcap_findalldevs(&allDevs,errMsgBuffer)==-1) { cout<<"未找到设备\n"< return0; } pt=allDevs; fp=pcap_open_live(pt->name,1000,1,3*1000,errMsgBuffer);//打开连接,超时为1秒 if(fp==NULL) { pcap_freealldevs(allDevs); cout<<"打开连接失败...%s\n"< return0; } //检测设备是否为以太网类型 if(pcap_datalink(fp)! =DLT_EN10MB||pt->addresses==NULL) { cout<<"该设备连接类型不支持\n"< return0; } netMask=((sockaddr_in*)(pt->addresses->netmask))->sin_addr.S_un.S_addr; //编译过滤程序 if(pcap_compile(fp,&fcode,packetFilter,1,netMask)<0) { cout<<"不能编译过滤包程序\n"< pcap_freealldevs(allDevs); return0; } //设置过滤包程序 if(pcap_setfilter(fp,&fcode)<0) { cout<<"不能设置过滤包程序\n"< pcap_freealldevs(allDevs); return0; } cout<<"\t\tListeningon"< ofstreamfout(agrv[0],ios: : app); if((int)fout.tellp()! =0) fout< time_tt; time(&t); fout.seekp(0,ios: : end); fout<<"\t\tARPrequest (1)/reply (2)on"< cout<<"SrcIPAddrSrcMACAddressDstIPAddrDstMACAddrOPTime"< fout<<"SrcIPAddrSrcMACAddressDstIPAddrDstMACAddrOPTime"< pcap_freealldevs(allDevs); intres; while((res=pcap_next_ex(fp,&header,&pktData))>=0) { if(res==0)//超时的话就继续 continue; packetHandler(header,pktData,cout); packetHandler(header,pktData,fout); } return0; } voidpacketHandler(constpcap_pkthdr*hdr,constunsignedchar*pkt_data,ostream&out) { ARPPKT*arph=(ARPPKT*)(pkt_data+14); //输出源ip地址 for(inti=0;i<3;i++) { out< } out.setf(ios: : left); out< out.unsetf(ios: : left); //输出源mac地址 charoldfillchar=out.fill('0'); out.setf(ios: : uppercase); for(i=0;i<5;i++) out< (2)< out< (2)< out.fill(oldfillchar); //输出目的ip地址 out.unsetf(ios: : hex|ios: : uppercase); for(i=0;i<3;i++) out< out.setf(ios: : left); out< out.unsetf(ios: : left); //输入目的mac地址 out.fill('0'); out.setf(ios: : uppercase); for(i=0;i<5;i++) out< (2)< out< (2)< out.fill(oldfillchar); out.unsetf(ios: : hex|ios: : uppercase); out< tm*ltime; time_tttemp(header->ts.tv_sec); ltime=localtime(&ttemp); out< '< (2)< '< (2)< out.fill(oldfillchar); out< } 六、总结 要做好这个课程设计,得先对计算机网络相关有更多的了解,首先对之前学习的课程进行了回顾和扩展,找了很多相关资料。 通过阅读相关资料,我大致掌握了ARP协议的详细过程。 在网际协议中定义的是因特网的IP地址,但在实际进行通信时,物理层不能识别IP地址只能识别物理地址。 因此,需在IP地址与物理地址之间建立映射关系,地址之间的这种映射称为地址解析。 ARP地址解析协议就是实现地址之间的这种映射关系的。 ARP地址解析协议的整个运作过程我简单的理解为: 源主机广播一个ARP请求报文,请求目的主机回答其物理地址。 网上所有主机都能收到该ARP请求,并将本机IP地址与请求的IP地址比较,目的主机识别出自己的地址IP,并作出回应,通报自己的物理地址。 源主机收到这个ARP回应包后,就可以与目的主机进行通信。 了解APR协议的过程,是编写程序的基本要求。 通过本次课程设计,使我们对网络方面的知识有了更深入的认识。 深刻体会了ARP协议的帧结构及运作过程,让我们把网络课上学到得书面的知识在实践中加以运用,深入理解。 课程设计过程中,遇到过很多问题,通过从网上查找解决问题的方法,不断的思考和调试运行,最后终于运行成功了,提升了自己解决问题的能力。 另外,在课程设计过程中,自己的编程能力也得到了巩固和提高。 七、参考文献 [1]谢希任.计算机网络(第五版[M].北京: 电子工业出版社,2012. [2]吴功宜,董大凡,王珺,刘乾.计算机网络高级软件编程技术(第二版)[M].北京: 清华大学出版社,2011.
- 配套讲稿:
如PPT文件的首页显示word图标,表示该PPT已包含配套word讲稿。双击word图标可打开word文档。
- 特殊限制:
部分文档作品中含有的国旗、国徽等图片,仅作为作品整体效果示例展示,禁止商用。设计者仅对作品中独创性部分享有著作权。
- 关 键 词:
- 东北大学 秦皇岛 分校 网络 课程设计