1、计算机网络课程设计报告计算机网络课程设计报告题目:ARP报文发送和解析一需求分析:网络层,数据被组装成IP包。但是发送IP包需要物理设备的支持(通常是Ethernet设备,在本课程设计中我们指定为Ethernet设备),即发送端必须知道目的物理地址才能将IP包发送出去,所以需要一种将IP地址映射为物理地址的机制。ARP协议就是用来完成这个任务的。ARP协议能够在网络上的每台主机或设备都有一个或多个IP地址。IP地址是网络层的地址。在同一个物理网络中,在给定目的主机或设备的IP地址的条件下,得到目的主机或设备的物理地址。ARP报文发送需求:ARP分组必须在数据链路层被封装成帧,才能发送出去。实现
2、地址解析协议的第一步是产生ARP请求分组。在相应的字段写入本地主机的源物理地址,源IP地址,目的IP地址;目的主机发送ARP应答分组,在ARP应答分组中,以请求分组中源物理地址,源IP地址作为其目的物理地址,目的IP地址,并将目的主机自身的物理地址,IP地址填入应答报文的源物理地址,源IP地址字段。在程序设计过程中,需要用到Winpcap,Winpcap是Win32环境下数据包捕获的开放代码函数库,基于Winpcap的应用程序一般按照下面几个步骤进行设计:打开网卡设备列表。选择网卡并打开。发送数据包。首先,需要获得主机中的网卡列表,可以使用pacap_findalldevs()函数;然后,选择
3、列表中的某个网卡,可以使用pacap_open_live()函数;最后,将封装好的ARP包发送到目的主机,可以使用pacap_sendpacket()函数。获取网卡列表后要求输入相应的源MAC地址,目的MAC地址,源IP地址,目的IP地址,这个时候就需要定义变量将输入的值在窗口上显示出来,可以使用GetWindowText()函数来显示输入的网卡信息,源MAC地址,目的MAC地址;对于IP地址,一般使用GetAddress()函数来显示出来。要求构造ARP包,用三个数据结构体来定义ARP的头部,以太网的头部和用来填充的部分,然后对ARP各字段进行填充,在对ARP各字段进行填充时要注意主机字节序
4、和网络字节序的转换,一般用到htons()函数,即将本地主机字节序转换为网络字节序,避免地址转换出现错误。ARP数据包构造完成后就可以实现发送。根据发送请求报文还是应答报文对目的MAC地址进行赋值,并对ARP数据包进行0填充。ARP包构造完成后发送报文,要求打开输出设备,将输入的地址信息输出发送,继而进行释放设备列表,清除资源。2概要设计:1.结构定义:根据ARP包结构,分别定义两个子结构:ARP帧结构和以太网帧结构。/ARP帧结构struct _ARP_HEAD USHORT hardware_type; /硬件类型 0x0001 USHORT protocal_type; /协议类型 0x
5、0800 UCHAR hardware_addr_len; /硬件地址长度 06 UCHAR protocal_addr_len; /协议地址长度 04 USHORT operation_field; /操作字段 01 request , 02 response UCHAR source_mac_addr6; /源mac地址 will be filled in runtime UCHAR source_ip_addr4; /源ip地址 localhost UCHAR dest_mac_addr6; /目的max地址 00:00:00:00:00:00 UCHAR dest_ip_addr4;
6、/目的ip地址 ;/ 以太网帧结构struct _ETHER_HEAD UCHAR dest_mac_addr6; /目的 mac 地址 UCHAR source_mac_addr6; /源 mac 地址 USHORT type; /帧类型 ;1.流程图: NY NY NY NY 三详细设计1.定义ARP数据包及初始化:/*构造ARP数据包*/struct _ARP _ETHER_HEAD eh; _ARP_HEAD ah; UCHAR padding18; / to make sure the sizeof(BYTES) = 60 ; _ARP arp;FormatMAC(arp.eh.so
7、urce_mac_addr, user);/将输入的MAC地址转换为十六进制并且以字符串形式输出arp.eh.type = htons(USHORT)0x0806);/arp数据包arp.ah.hardware_type = htons(USHORT)0x0001);arp.ah.protocal_type = htons(USHORT)0x0800);arp.ah.hardware_addr_len = (UCHAR)0x06;arp.ah.protocal_addr_len = (UCHAR)0x04;arp.ah.source_ip_addr0 = field0;/源IP赋值arp.ah
8、.source_ip_addr1 = field1;arp.ah.source_ip_addr2 = field2;arp.ah.source_ip_addr3 = field3;arp.ah.dest_ip_addr0 = field4;/目的IP赋值arp.ah.dest_ip_addr1 = field5;arp.ah.dest_ip_addr2 = field6;arp.ah.dest_ip_addr3 = field7;请求报文与应答报文(0表示请求,1表示应答)在填充请求包时,因为请求包在Ethernet上广播,所以以太网头部的目的MAC地址要填充为FFFFFFFFFFFF;ARP
9、帧结构中的目的地址可填充为任意数,因为它此时不起作用,所以填充数据字段要填充为。if (flag = 0) arp.ah.operation_field = htons(0x0001);/地址转换 for (i = 0; i 6; i+) arp.eh.dest_mac_addri = (UCHAR)0xff; arp.ah.dest_mac_addri = (UCHAR)0x00; else arp.ah.operation_field = htons(0x0002); FormatMAC(arp.eh.dest_mac_addr, c_user); FormatMAC(arp.ah.des
10、t_mac_addr, c_user); for (i = 0; i next) CString temp(d-name); if (Netname=temp) break; if (d= NULL) MessageBox(_T(ERROR); exit(-1); /* 打开输出设备 */ if (fp = pcap_open(d-name, / 设备名 100, / 要捕获的部分 (只捕获前100个字节) PCAP_OPENFLAG_PROMISCUOUS, / 混杂模式 1000, / 读超时时间 NULL, / 远程机器验证 errbuf / 错误缓冲 ) = NULL) Message
11、Box(_T(1); exit(-1); /* 释放设备列表 */ pcap_freealldevs(alldevs);5.发送数据包/定义变量 CString Netname; pcap_t *fp; char errbufPCAP_ERRBUF_SIZE; int i; pcap_if_t *alldevs; pcap_if_t *d; pcap_t *adhandle; /*获取界面的值*/ GetDlgItem(IDC_COMBO1)-GetWindowText(Netname); CString c_user; address1.GetWindowText(c_user); CStr
12、ing user; address2.GetWindowText(user); BYTE field0, field1, field2, field3; this-address3.GetAddress(field0, field1, field2, field3); CString ip; ip.Format(_T(%d.%d.%d.%d), field0, field1, field2, field3); BYTE field4, field5, field6, field7; this-address4.GetAddress(field4, field5, field6, field7)
13、;CString ip1;ip1.Format(_T(%d.%d.%d.%d), field4, field5, field6, field7);if (pcap_sendpacket(fp, (const u_char*)&arp, 60) != 0) exit(-1); MessageBox(_T(OK);4调试分析在对ARP包中各字段进行填充时,需要注意主机字节序和网络字节序的转换。例如:arp.ah.hardware_type = htons(USHORT)0x0001);在获取主机中的网卡列表时,我们可以使用pcap_findalldevs()函数;选择并打开列表里的某个网卡, 可以
14、使用pcap_open_live()函数;在将封装好的ARP包发送到目的主机时,可以使用pcap_sendpacket()函数。在遇到获取界面的值有误的情况下,我们可以使用MessageBox()函数用来调试。在退出按钮的代码编写中,一般不使用exit()函数,不知道具体原因,我在编辑代码的过程中使用这个函数就会出现错误,因此我使用CDialog:OnCancel()函数提出,该函数就是响应WM_CLOSE消息,调DestroyWindow将窗口句柄关掉。点击一个按钮跳出另一个窗口,可以在按钮的实现代码中用到DoModal()函数。在MFC中创建实现一个窗口后,如果还要新建一个窗口,就必须给此
15、窗口添加类向导,使用该向导从可用的类型库添加MFC类。该向导为从选定的类型库添加的每个接口创建类。在对控件进行具体实现之前,必须要对控件添加变量,以用来获取控件的取值以及具体函数的实现,这一步至关重要。在程序设计过程中要注意网络主机 字节顺序的转化。由于不同的计算机系统所采用的数据表示方式不同,对于2B或4B的数据,有的采用低字节地址存放数据的高权值位,而有的却以低地址字节存放数据的低权位值,在网络的数据传输中,我们应该统一标示,所以我们应将数据包头部的表示长度或类型的数据转换成本地机的表达形式。可以了利用htohs()将网络字节序转换为主机字节序,这也是不能忽略的问题,如果不注意,就会出现地
16、址转换的错误。以下为执行调试界面:五课设总结 在本次课程设计中,收获颇多。从刚开始安装Visual studio,配置安装环境,再到建立MFC工程,这个过程中,XX成了我最好的老师,最后终于搞定。通过本次课程设计,对MFC也是了解了很多,通过网上查找博客,了解了MFC中控件的用法以及属性设置,虽然理解可能还不是那么的透彻,但最基本的使用还是掌握了。这次课设的顺利完成,主要是参考了WinpCap中文文档,网络编程的一些主要算法,文档都有举例说明,也有详细的说明,这极大的帮助了我完成一些代码的处理,也促进了理解。通过这次课程设计,也让我学会了独立思考解决问题,虽然很多还是通过XX来解决,但至少也是
17、自己思考的过程,我也觉得和同学交流讨论也很重要,虽然自己也有想法,但也不一定就是对的,可行的,通过和大家一起讨论,就会避免出现一些不必要的问题,也可以促进自己的理解。通过自己做ARP发送,也进一步具体的了解了ARP协议的具体执行,也通过封装ARP包进一步掌握了ARP包的结构。总而言之,通过这次网络课程设计,自己学到了不少东西,对网络编程也有了一定意义上的理解和认识,深刻体会了ARP协议的帧结构及运作过程,让我们把网络课上学到的东西在实践中加以运用,本次课程设计确实不太容易做,很多东西都没有学过,整个过程大多数都是在借鉴WinpCap文档里的程序,但我相信,这对我以后学习网络应用知识也具有很大的帮助。
copyright@ 2008-2022 冰豆网网站版权所有
经营许可证编号:鄂ICP备2022015515号-1