计算机网络课程设计报告题目:解析ARP数据包姓名:学号:同组姓名:专业班级:指导教师:评阅意见:评定成绩:指导老师签名:年月日1目录一、课程设计目的:...............................2二、课程设计要求:...............................2三、课程设计分析.................................31.课程设计中的重点及难点......................32.参考算法.....................................33.核心代码.....................................4四、源程序及运行截图.............................5五、心得体会.....................................9六、参考文献....................................102一、课程设计目的:本课程设计的目的是对网络上的ARP数据包进行解析,从而熟悉ARP数据包的结构,对ARP协议有更好的理解和认识。二、课程设计要求:通过编制程序,获取网络中的ARP数据包,解析数据包的内容,将结果显示在标准输出上,并同时写入日志文件。程序的具体要求如下所示:1.以命令行的形式运行,如下所示:arpparselogfile其中,arpparse为程序名;logfile为日志文件名。2.程序输出内容如下所示:源IP地址源MAC地址目的IP地址操作时间各部分的说明如下所示:源IP地址:输出ARP消息格式中的源IP地址字段。源MAC地址:输出ARP消息格式中的源物理地址字段。目的IP地址:输出ARP消息格式中的目的IP地址字段。目的MAC地址:输出ARP消息格式中的目的物理地址字段。操作:输出ARP消息格式中的操作字段,若为ARP请求,则为1,若为ARP应答,则为2。时间:该ARP包产生的时间3.当程序接收到键盘输入Ctrl+C时退出。3三、课程设计分析1.课程设计中的重点及难点1)程序中会用到Winpcap,Winpcap是Win32环境下数据包捕获的开放代码函数库。基于Winpcap的应用程序一般按照下面几个步骤进行设计:输出网卡设备列表。选择网卡并打开。捕获数据包时,可能需要设置过滤器。捕获数据包或者发送数据包。2)在程序设计过程中需要注意网络—主机字节顺序的转化。由于不同的计算机系统所采用的数据表示方式不同,对于2B或4B的数据,有的采用低字节地址存放数据的高权值位,而有的却以低地址字节存放数据低权位值,在网络的数据传输中,我们应该统一表示,所以我们在捕获数据包后,应将数据包头部的表示长度或类型的数据转换成本地机的表达形式。可以利用函数ntohs()将网络字节序转换为主机字节序。3)选择网卡并打开时,注意选择可用的网卡。2.参考算法1)取得当前网卡设备列表。2)选择Ethernet网卡并打开,注意判断所选网卡是否为实际存在的可用网卡。3)设置过滤器,此处的过滤器正则表达式为“arp”或者“etherproto\\arp”。4)捕获数据包并进行处理(包括输出各IP地址,物理地址,操作类型以及时间)。由于要记录日志文件,为了便于输出流参数,建议采用pcap_next_ex()函数。流程图如下图所示:43.核心代码ARP数据包结构structarppkt{unsignedshorthdtyp;//硬件类型。值0001表示其为Ethernetunsignedshortprotyp;//协议类型。值0800表示上层协议为IPunsignedcharhdsize;//硬件地址长度。值为06unsignedcharprosize;//协议地址长度。值为04unsignedshortop;//操作值为0001/0002,分别表示ARP请求/应答u_charsmac[6];//源MAC地址,6Bu_charsip[4];//源IP地址,4Bu_chardmac[6];//目的MAC地址u_chardip[4];//目的IP地址};获取网络设备列表,并以混杂模式打开网络设备//获取网络设备列表if(pcap_findalldevs(&alldevs,errbuf)==-1){coutErrorinpcap_findalldevs:errbuf;return;}开始获取网卡列表选取Ethernet网卡打开网卡(混杂模式)编译设置过滤器捕获ARP包并将其相应内容输出5//选择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数据包的各个域的内容到文件和屏幕上}四、源程序及运行截图1.源程序如下:#includewinsock2.h#pragmacomment(lib,Ws2_32.lib)//用到ntobs()//等同于点击project-setting-link打开object/librarymodule编辑框后加入文件#pragmacomment(lib,wpcap.lib)6#includepcap.h//此头文件没有包含在VC中,需要另外加入#includefstream.h#includeiomanip.h//格式化输出需要用到#includeconio.h//用到_getch()//注意到接收的数据包头中代表类型,数据长度的字段采用的是big-endian//所以对于2B/4B的数据要用ntohs()转换为本机形式//ARP包结构structarppkt{unsignedshorthdtyp;//硬件类型。值0001表示其为Ethernetunsignedshortprotyp;//协议类型。值0800表示上层协议为IPunsignedcharhdsize;//硬件地址长度。值为06unsignedcharprosize;//协议地址长度。值为04unsignedshortop;//操作值为0001/0002,分别表示ARP请求/应答u_charsmac[6];//源MAC地址,6Bu_charsip[4];//源IP地址,4Bu_chardmac[6];//目的MAC地址u_chardip[4];//目的IP地址};voidpacket_handler(constpcap_pkthdr*header,constu_char*pkt_data,ostream&out);voidmain(intargc,char*argv[]){if(argc!=2){coutUsage:arpparselogfilenameendl;coutpressanykeytocontinue.endl;_getch();return;}pcap_if_t*alldevs;pcap_if_t*d;pcap_t*adhandle;charerrbuf[PCAP_ERRBUF_SIZE];u_intnetmask;charpacket_filter[]=etherproto\\arp;structbpf_programfcode;structpcap_pkthdr*header;constu_char*pkt_data;if(pcap_findalldevs(&alldevs,errbuf)==-1){coutErrorinpcap_findalldevs:errbuf;return;}for(d=alldevs;d;d=d-next)7{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-addressess!=NULL)break;}if(d==NULL){cout\nNointerfacesfound!MakesureWinpcapisinstalled.\n;return;}//获得子网掩码netmask=((sockaddr_in*)(d-netmask))-sin_addr.s_un.s_addr;//编译过滤器,只捕获ARP包if(pcap_compile(adhandle,&fcode,packet_filter,1,netmask)0){cout\nUnabletocompilethepacketfilter.Checkthesyntax.\n;pcap_freealldevs(alldevs);return;}//设置过滤器if(pcap_setfilter(ashandle,&fcode)0){cout\nErrorsettingthefilter.\n;pcap_freealldevs(alldevs);return;}cout\t\tlisteningond-description...endlendl;//显示提示信息及每项含义ofstreamfout(argv[1],ios::app);//日志记录文件//为了查看日志时的方便,其中加入了日期记录time_tt;time(&t);fout.seekp(0,ios::end);if(fout.tellp()!=0)foutendl;fout\t\tARPrequest(1)/reply(2)onctime(&t);coutSourIpAddrSourMACAddressDesIpAddrDesMACAddressOPTimeendl;foutSourIpAddrSourMACAddressDesIpAddrDesMACAddress8OPTimeendl;//释放设备列表pcap_freealldevs(alldevs);intresult;while((result=pcap_next_ex(adhandle,&header,&pkt_data))=0){if(result==0)continue;packer_handler(header,pkt_data,cout);packet_handler(heade