分类: LINUX
2009-10-12 15:23:13
前 言
首先要感谢网络安全资深专家卢湖川博士以及VC网络版的limin朋友提供的资料以及帮助^_^
经常看到论坛有人问起关于数据包的截获、分析等问题,幸好本人也对此略有所知,所以就想写一系列的文章来详细深入的探讨关于数据包的知识,,我希望通过这一系列的文章,能使得关于数据包的知识得以普及,所以这系列的每一篇文章我都会有由浅入深的解释、详细的分析、以及编码步骤,另外附上带有详细注释的源码(为了照顾大多数朋友,我提供的都是MFC的源码)。
不过由于也是初学者,疏漏之处还望不吝指正。
本文凝聚着笔者心血,如要转载,请指明原作者及出处,谢谢!^_^
OK,. Let’s go ! Have fun!! q^_^p
第一篇 手把手教你玩转ARP包
目录:
一. 关于ARP协议的基础知识
1. ARP的工作原理
2. ARP包的格式
作者:
CSDN VC/MFC 网络编程 PiggyXP ^_^
一. 关于ARP协议的基础知识
1.ARP的工作原理
本来我不想在此重复那些遍地都是的关于ARP的基本常识,但是为了保持文章的完整性以及照顾初学者,我就再啰嗦一些文字吧,资深读者可以直接跳过此节。
我们都知道以太网设备比如网卡都有自己全球唯一的MAC地址,它们是以MAC地址来传输以太网数据包的,但是它们却识别不了我们IP包中的IP地址,所以我们在以太网中进行IP通信的时候就需要一个协议来建立IP地址与MAC地址的对应关系,以使IP数据包能发到一个确定的地方去。这就是ARP(Address Resolution Protocol,地址解析协议)。
讲到此处,我们可以在命令行窗口中,输入
arp –a
来看一下效果,类似于这样的条目
210.118.45.100 00-0b
就是我们电脑里存储的关于IP地址与MAC地址的对应关系,dynamic表示是临时存储在ARP缓存中的条目,过一段时间就会超时被删除(xp/2003系统是2分钟)。
这样一来,比如我们的电脑要和一台机器比如210.118.45.1通信的时候,它会首先去检查arp缓存,查找是否有对应的arp条目,如果没有,它就会给这个以太网络发ARP请求包广播询问210.118.45.1的对应MAC地址,当然,网络中每台电脑都会收到这个请求包,但是它们发现210.118.45.1并非自己,就不会做出相应,而210.118.45.1就会给我们的电脑回复一个ARP应答包,告诉我们它的MAC地址是xx-xx-xx-xx-xx-xx,于是我们电脑的ARP缓存就会相应刷新,多了这么一条:
210.118.45.1 xx-xx-xx-xx-xx-xx dynamic
为什么要有这么一个ARP缓存呢,试想一下如果没有缓存,我们每发一个IP包都要发个广播查询地址,岂不是又浪费带宽又浪费资源?
而且我们的网络设备是无法识别ARP包的真伪的,如果我们按照ARP的格式来发送数据包,只要信息有效计算机就会根据包中的内容做相应的反应.
试想一下,如果我们按照ARP响应包的相应的内容来刷新自己的ARP缓存中的列表,嘿嘿,那我们岂不是可以根据这点在没有安全防范的网络中玩些ARP包的小把戏了?在后面的文章里我就手把手来教你们如何填充发送ARP包,不过先别急,我们再继续学点基础知识^_^
2.ARP包的格式
既然我们要来做一个我们自己的ARP包,当然首先要学习一下ARP包的格式。
从网络底层看来,一个ARP包是分为两个部分的,前面一个是物理帧头,后面一个才是ARP帧。
首先,物理帧头,它将存在于任何一个协议数据包的前面,我们称之为DLC Header,因为这个帧头是在数据链路层构造的,并且其主要内容为收发双方的物理地址,以便硬件设备识别。
DLC Header | |||
字段 | 长度(Byte) | 默认值 | 备注 |
接收方MAC | 6 | 广播时,为 ff-ff-ff-ff-ff-ff | |
发送方MAC | 6 | ||
Ethertype | 2 | 0x0806 | 0x0806是ARP帧的类型值 |
图1 物理帧头格式
图1是需要我们填充的物理帧头的格式,我们可以看到需要我们填充的仅仅是发送端和接收端的物理地址罢了,是不是很简单呢?
ARP Frame | |||
字段 | 长度(Byte) | 默认值 | 备注 |
硬件类型 | 2 | 0x1 | 以太网类型值 |
上层协议类型 | 2 | 0x0800 | 上层协议为IP协议 |
MAC地址长度 | 1 | 0x6 | 以太网MAC地址长度为 6 |
IP地址长度 | 1 | 0x4 | IP地址长度为 4 |
操作码 | 2 | 0x1表示ARP请求包,0x2表示应答包 | |
发送方MAC | 6 | ||
发送方IP | 4 | ||
接收方MAC | 6 | ||
接收方IP | 4 | ||
填充数据 | 18 | 因为物理帧最小长度为64字节,前面的42字节再加上4个CRC校验字节,还差18个字节 |
图2 ARP帧格式
我们可以看到需要我们填充的同样也只是MAC,IP,再加上一个1或2的操作码而已。
二. 发送ARP包的编程实现 1. 填充数据包 上面的那些关于ARP包各个字段的表格,对应在程序里就是结构体,对应于上面的表格,于是我们需要三个下面这样的结构体 // DLC Header typedef struct tagDLCHeader { unsigned char DesMAC[6]; /* destination HW addrress */ unsigned char SrcMAC[6]; /* source HW addresss */ unsigned short Ethertype; /* ethernet type */ } DLCHEADER, *PDLCHEADER; // ARP Frame typedef struct tagARPFrame { unsigned short HW_Type; /* hardware address */ unsigned short Prot_Type; /* protocol address */ unsigned char HW_Addr_Len; /* length of hardware address */ unsigned char Prot_Addr_Len; /* length of protocol address */ unsigned short Opcode; /* ARP/RARP */ unsigned char Send_HW_Addr[6]; /* sender hardware address */ unsigned long Send_Prot_Addr; /* sender protocol address */ unsigned char Targ_HW_Addr[6]; /* target hardware address */ unsigned long Targ_Prot_Addr; /* target protocol address */ unsigned char padding[18]; } ARPFRAME, *PARPFRAME; // ARP Packet = DLC header + ARP Frame typedef struct tagARPPacket { DLCHEADER dlcHeader; ARPFRAME arpFrame; } ARPPACKET, *PARPPACKET; 这些结构体一定能看懂吧,在程序中就是对号入座就好了