logo资料库

ARP协议获得局域网内活动主机物理地址程序.doc

第1页 / 共16页
第2页 / 共16页
第3页 / 共16页
第4页 / 共16页
第5页 / 共16页
第6页 / 共16页
第7页 / 共16页
第8页 / 共16页
资料共16页,剩余部分请下载后查看
项目设计报告
1.需求分析
1.1问题重述
2概要设计
2.1原理概述
2.2主要问题
2.3数据结构
3 详细设计
3.1 主要函数说明
4 运行结果
5 实验总结
5 参考文献
<ARP 协议获得局域网内活动主机物理地址程序> 项目设计报告 1. 需求分析 实验目的:使用 ARP 发现局域网内活动主机,自行构造、发送 ARP 请求 数据帧,加深对 ARP 协议的了解。 实验任务:(1)掌握 ARP 协议分组结构与协议运作过程; (2) 了解 ARP 协议获取活动主机 MAC 地址的方法与软件实现; (3)在 windows/linux 平台上构造自定义数据帧,并通过指定网络适配 器(网卡)发送的基本方法。 实验环境:1~2 台 PC 机 操作系统:Windows XP 开发环境:Microsoft Visual C++ 6.0 ,winpcap;可以使用 MFC 类库 1.1 问题重述 (1)梳洗 arp 数据帧格式和字段含义以及 arp 协议运作过程 (2)了解 Winpcap 开发包的使用方法, (3) 掌握 windows 平台构造自定义数据帧,并通过指定的网络适配器发送的 基本过程。 应用现状综述: Ethernet 是目前使用最为广泛的局域网,它基于 802.3 协议,主机间通过网 卡的 MAC(Media Access Control)地址(即物理地址)进行通信。 Arp 协议工作在 TCP/IP 协议的第二层(数据链路层)。用于将 IP 地址转换为 网卡物理地址(NIC 的 MAC 地址,媒体访问控制地址)。无论是任何高层协议的 通信,最终都将转换为数据链路层的 MAC 地址来通信。所以说,ARP 协议是保证 网络通信的基础协议。 ARP 攻击就是通过伪造 IP 地址和 MAC 地址实现 ARP 欺骗,能够在网络中产生大
量的 ARP 通信量使网络阻塞,攻击者只要持续不断的发出伪造的 ARP 响应包就能 更改目标主机 ARP 缓存中的 IP-MAC 条目,造成网络中断或中间人攻击。 2 概要设计 2.1 原理概述 1 课程设计中涉及的网络基本理论简介: (1) 在网际协议中定义的是因特网的 IP 地址,但在实际进行通信时,物理层 不能识别 IP 地址只能识别物理地址。因此,需在 IP 地址与物理地址之 间建立映射关系,地址之间的这种映射称为地址解析。 (2) 以太网网络中的物理地址即网卡的序列号。IEEE 规定网卡序列号为 6 个 字节(48 位),前三个字节为厂商代号,由于厂商向 IEEE 注册登记申请, 后 3 个字节为网卡的流水号。 (3) 地址解析包括从 IP 地址到物理地址的映射和从物理地址到 IP 地址的映 射。TCP/IP 协议组提供了两个映射协议:地址解析协议 ARP 和逆向地址 解析协议 RARP。ARP 用于从 IP 地址到物理地址的映射,RARP 用于从物理 地址到 IP 地址的映射。 (4) 地址解析协议的 ARP 的工作原理:假定在一个物理网络上,A(源主机) 要与 D(目的主机)进行通信,但是不知道 D 的物理地址。 A 利用 ARP 协议工作的过程如下: A 广播一个 ARP 请求报文,请求 IP 地址为 IPD 的主机回答其物理地址。 网上所有主机都能收到该 ARP 请求,并将本机 IP 地址与请求的 IP 地址比 较,D 主机识别出自己的地址 IPD,并作出回应,通报自己的物理地址。A 收到这个 ARP 回应包后,就可以与 D 进行通信。 为了提高效率,ARP 协议使用了高速缓存技术。在每台使用 ARP 的主机中,都 保留了一个专用的内存区,一收到 ARP 应答,主机就将获得的 IP 地址和物理地址存 入缓存。以后每次要发送报文时,首先到缓存中查找有无相应的项,若找不到,再 利用 ARP 进行地址解析。由于多数网络通信都要连续发送多个报文,所以高速缓存 大大提高 ARP 的效率。 在 ARP 请求报文中还放入源主机的“IP 地址——物理地址”的地址对,源主机 在广播 ARP 请求时,网络上所有主机都可以知道该源主机的“IP 地址——物理地址” 的地址对并将其存入自己的缓存。 在新主机入网时,令其主动广播其地址映射,以减少其他主机进行 ARP 请求。 (5) 网卡具有如下的几种工作模式: 广播模式(Broad Cast Model):它的物理地址(MAC)地址是 0Xffffff 的帧为广播帧,工作在广播模式的网卡接收广播帧。 多播传送(MultiCast Model):多播传送地址作为目的物理地址的帧可 以被组内的其它主机同时接收,而组外主机却接收不到。但是,如果将 网卡设置为多播传送模式,它可以接收所有的多播传送帧,而不论它是 不是组内成员。 直接模式(Direct Model):工作在直接模式下的网卡只接收目地址是自 己 Mac 地址的帧。
混杂模式(Promiscuous Model):工作在混杂模式下的网卡接收所有的 流过网卡的帧,信包捕获程序就是在这种模式下运行的。 (6) ARP 帧的数据结构表达方式: 以太网帧头中的前两个字段是以太网的目的地址和源地址。目的地址 为全 1 时为广播地址。 两个字节长的以太网帧类型表示后面数据的类型。对于 ARP 请求或应 答来说,该字段的值为 0X0806. 硬件类型字段:指明了发送方想知道的硬件地址的类型,以太网的值 为 1; 协议类型字段:表示要映射的协议地址类型,IP 为 0X0800; 硬件地址长度和协议地址长度:指明了硬件地址和高层协议地址的长 度,这样 ARP 帧就可以在任意硬件和任意协议的网络中使用。对于以太网 上 IP 地址的 ARP 请求或应答来说,它们的值分别为 6 和 4; 操作字段:用来表示这个报文的类型,ARP 请求为 1,ARP 响应为 2, RARP 请求为 3,RARP 响应为 4; 发送端的以太网地址:源主机硬件地址,6 个字节; 发送端 IP 地址:发送端的协议地址(IP 地址),4 个字节; 目的以太网地址:目的端硬件地址,6 个字节; 目的 IP 地址:目的端的协议地址(IP 地址),4 个字节。 2. 2 主要问题 1.ARP 相关数据帧结构 2.ARP 协议工作原理 3.程序的流程 4. Winpcap 开发包的使用方法 5.Windows 平台构造自定义数据帧,并通过指定网络适配器发送的方法。 解决思路: (1).先查找资料,深入掌握 ARP 的相关数据帧结构,工作原理。并且对要编 程的 ARP 程序的流程进行熟悉。 (2).查阅资料,掌握 Winpcap 开发包的使用方法。 (3).查阅资料,掌握通过指定网络适配器发送数据帧的方法。 实现预期目标的可行性分析: ARP 协议工作在 TCP/IP 的第二层,用于将 IP 地址转换为网卡的物理地址。 通过一定时间的学习,熟悉 ARP 协议和 Winpcap 开发包使用方法,并且在老师的 细心指导下,本课题中遇见的问题可以迎刃而解。顺利完成程序的开发。 本论文主要通过对 ARP 协议的帧结构,ARP 原理,工作流程等的分析来完成 获取局域网内活动主机的物理地址的程序的开发。第一章主要介绍当前计算机网 络,协议的发展。第二章主要描述网络基础知识和 ARP 协议的原理,帧结构等相 关知识。第三章主要介绍 ARP 软件开发时使用的工具,包括 Visual C++和 Winpcap
开发包。第四章为 ARP 软件的详细设计,主要包括 ARP 软件的工作程序的编写, 和 ARP 软件界面的设计。第五章为总结,对本文进行最终的归纳。 2.3 数据结构 struct ethernet_head { unsigned char dest_mac[6]; unsigned char source_mac[6]; unsigned short eh_type; //目标主机 MAC 地址 /源端 MAC 地址 //以太网类型 }; struct arp_head { unsigned short hardware_type; unsigned short protocol_type; unsigned char add_len; unsigned char pro_len; unsigned short option; unsigned char sour_addr[6]; unsigned long sour_ip; unsigned char dest_addr[6]; //硬件类型:以太网接口类型为 1 //协议类型:IP 协议类型为 0X0800 //硬件地址长度:MAC 地址长度为 6B //协议地址长度:IP 地址长度为 4B //操作:ARP 请求为 1,ARP 应答为 2 /源 MAC 地址:发送方的 MAC 地址 //源 IP 地址:发送方的 IP 地址 //目的 MAC 地址:ARP 请求中该字段 没有意义;ARP 响应中为接收方的 MAC 地址 unsigned long dest_ip; //目的 IP 地址:ARP 请求中为请求解析 的 IP 地址;ARP 响应中为接收方的 IP 地址 unsigned char padding[18]; }; //最终 arp 包结构 //以太网头部 //arp 数据包头部 struct arp_packet { ethernet_head eth; arp_head arp; }; 3 详细设计 3.1 主要函数说明
/**************** *物理帧头部结构 *****************/ typedef struct { ethernet_head unsigned char unsigned char unsigned short eh_dest_mac[6]; eh_source_mac[6]; eh_type; }ethernet_head, *pEthernetHead; //目标主机 mac //本地主机 mac //类型 /************ *ARP 帧结构 *************/ typedef struct { arpHead unsigned short unsigned short unsigned char unsigned char unsigned short unsigned char unsigned long unsigned char unsigned long unsigned char arp_hardwaretype; arp_protocoltype; arp_har_len; arp_pro_len; arp_option; arp_sour_addr[6]; arp_sour_ip; arp_dest_addr[6]; arp_dest_ip; padding[18]; //硬件类型(2 bit) //协议类型(2 bit) //硬件地址长度(1 bit) //协议地址长度(1 bit) //操作号(2 bit) //源硬件地址(6 bit) //源协议地址(4 bit) //目的硬件地址(6 bit) //目的协议地址(4 bit) //填充数据(18 bit) }arpHead, *pArpHead; /**************** *IP 数据报头结构 *****************/ typedef struct ipHead { unsigned char unsigned char unsigned short unsigned short unsigned short h_lenver; tos; total_len; ident; frag_and_flags; // 版本 (4 bits) + 首部长度 (4 bits) // 服务类型(Type of service) // 总长(Total length) // 标识(Identification) // 标志位(Flags) (3 bits) + 段偏移量(Fragment offset) (13 bits) unsigned char unsigned char unsigned short unsigned int unsigned int ttl; proto; checksum; sourceip; destip; }ipHead, *PipHead; // 存活时间(Time to live) // 协议(Protocol) // 首部校验和(Header checksum) // 源地址(Source address) // 目的地址(Destination address)
#pragma pack(push) LPADAPTER ADAPTER structure 设备指针 LPPACKET PACKET structure 包指针 unsigned long unsigned char char int 增 lpadapter = 0; lppacketr, lppackets; myip; mymac[6] = {0}; adapterlist[MAX_NUM_ADAPTER][1024]; num = 0; //define a pointer to an //define a pointer to a //本地主机 IP //本地主机 mac 初始化 //本地主机网卡列表 //用于发送 ARP 包时候递 void start() { 局域网内活动主机检测 printf("************************************\n"); printf("* *\n"); *\n"); printf("* *\n"); printf("* printf("* *\n"); printf("************************************\n"); return; 07 微电子 董巍 2120070223 } /********************** *获得本地主机的 mac 地址 ***********************/ int getmine() { char int ethernet_head arpHead sendbuf[1024]; k; eth; arp; for(k=0;k<6;k++) { eth.eh_dest_mac[k] =0xff; eth.eh_source_mac[k]=0x82; arp.arp_sour_addr[k]=0x82; arp.arp_dest_addr[k]=0x00; } eth.eh_type=htons(ETH_ARP); arp.arp_hardwaretype=htons(ARP_HARDWARE);
arp.arp_protocoltype=htons(ETH_IP); arp.arp_har_len=6; arp.arp_pro_len=4; arp.arp_option=htons(ARP_REQUEST); arp.arp_dest_ip=htonl(myip); arp.arp_sour_ip=inet_addr("112.112.112.112"); memset(sendbuf,0,sizeof(sendbuf)); memcpy(sendbuf,e,sizeof(eth)); memcpy(sendbuf+sizeof(eth),&arp,sizeof(arp)); PacketInitPacket(lppackets,sendbuf,sizeof(eth)+sizeof(arp)); if(PacketSendPacket(lpadapter,lppackets,TRUE)==FALSE) { printf("PacketSendPacket in getmine Error: %d\n",GetLastError()); return -1; } return 0; } /**************** *解析数据报 *****************/ void receivedata(LPPACKET lppktr) { unsigned long unsigned long char PipHead struct bpf_hdr struct sockaddr_in ethernet_head arpHead ulbytesreceived, off; j; *buf, *pChar, *base; ip; *hdr; sin; *eth; *arp; ulbytesreceived = lppktr->ulBytesReceived; buf = (char *)lppktr->Buffer; off = 0; //解析数据报 while (off < ulbytesreceived) { //数据报头部
if(kbhit()) { return; } hdr = (struct bpf_hdr *)(buf+off); off += hdr->bh_hdrlen; //数据报头部长度 pChar = (char *)(buf+off); base = pChar; off = Packet_WORDALIGN(off + hdr->bh_caplen); eth = (pEthernetHead)pChar; arp = (pArpHead)(pChar + sizeof(ethernet_head)); if (eth->eh_type == htons(ETH_IP)) { ip = (PipHead)(pChar+sizeof(ethernet_head)); } else if((eth->eh_type==htons(ETH_ARP)) && (arp->arp_option==htons(ARP_REPLY))) { sin.sin_addr.s_addr = arp->arp_sour_ip; if (sin.sin_addr.s_addr == htonl(myip)) { memcpy(mymac, eth->eh_source_mac, 6); } //输出 ip 地址 printf("\n[IP:] %.16s [MAC:] ", inet_ntoa(sin.sin_addr)); //输出 mac 地址 for(j=0;j<5;j++) { printf("%.2x-",eth->eh_source_mac[j]); } printf("%.2x\n",eth->eh_source_mac[5]); } } return ; }
分享到:
收藏