捕获数据包
- 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
- 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
- 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
希望通过这一系列的文章,能使得关于数据包的知识得以普及,所以这系列的每一篇文章我都会有由浅入深的解释、详细的分析、以及编码步骤,另外附上带有详细注释的源码
文章作者:nirvana
经常看到论坛有人问起关于数据包的截获、分析等问题,幸好本人也对此略有所知,也写过很多的sniffer,所以就想写一系列的文章来详细深入的探讨关于数据包的知识。
我希望通过这一系列的文章,能使得关于数据包的知识得以普及,所以这系列的每一篇文章我都会有由浅入深的解释、详细的分析、以及编码步骤,另外附上带有详细注释的源码(为了照顾大多数朋友,我提供的都是MFC的源码)。
不过由于也是初学者,疏漏之处还望不吝指正。
本文凝聚着笔者心血,如要转载,请指明原作者及出处,谢谢!^_^
OK,. Let’s go ! Have f un!! 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-5f-e6-c5-d7 dynamic
就是我们电脑里存储的关于IP地址与MAC地址的对应关系,dynamic表示是临时存储在ARP缓存中的条目,过一段时间就会超时被删除(xp/2003系统是2分钟)。
这样一来,比如我们的电脑要和一台机器比如210.118.45.1通信的时候,它会首先去检查arp缓存,查找是否有对应的arp条目,如果没有,它就会给这个以太网络发ARP请求包广播询问210.118.45.1的对应MAC地址,当然,网络中每台电脑都
目录:
二。发送数据包的编程实现
1. 填充数据包
2. 发送数据包
三。一些附加步骤及说明
1. 如果在VC中使用winpcap
2. 获得网卡信息列表
3. 获得系统ARP信息列表
................紧接上文................
1.填充数据包
下面我举个填充包头的例子,我首先定义个了一个转换字符的函数,如下
/**************************************************************************** * Name & Params::
* formatStrToMAC
* (
* const LPSTR lpHWAddrStr : 用户输入的MAC地址字符串
* unsigned char *HWAddr : 返回的MAC地址字符串(赋给数据包结构体)
* )
* Purpose:
* 将用户输入的MAC地址字符转成数据包结构体需要的格式
****************************************************************************/ void formatStrToMAC(const LPSTR lpHWAddrStr, unsigned char *HWAddr)
{
unsigned int i, index = 0, value, temp;
unsigned char c;
_strlwr(lpHWAddrStr); // 转换成小写
for (i = 0; i < strlen(lpHWAddrStr); i++)
{
c = *(lpHWAddrStr + i);
if (( c>='0' && c<='9' ) || ( c>='a' && c<='f' ))
{
if (c>='0' && c<='9') temp = c - '0'; // 数字
if (c>='a' && c<='f') temp = c - 'a' + 0xa; // 字母
if ( (index % 2) == 1 )
{
value = value*0x10 + temp;
HWAddr[index/2] = value;
}
else value = temp;
index++;
}
if (index == 12) break;
}
}
// 开始填充各个字段
ARPPACKET ARPPacket; // 定义ARPPACKET结构体变量
memset(&ARPPacket, 0, sizeof(ARPPACKET)); // 数据包初始化
formatStrToMAC(“DLC源MAC字符串”,ARPPacket.dlcHeader.SrcMAC);// DLC帧头
formatStrToMAC(“DLC目的MAC字符串”,ARPPacket.dlcHeader.DesMAC);
formatStrToMAC(“ARP源MAC字符串”,ARPPacket.arpFrame.Send_HW_Addr);// 源MAC
ARPPacket.arpFrame.Send_Prot_Addr = inet_addr(srcIP); // 源IP
formatStrToMAC(“ARP目的MAC字符串”,ARPPacket.arpFrame.T arg_HW_Addr); // 目的MAC ARPPacket.arpFrame.T arg_Prot_Addr = inet_addr(desIP); // 目的IP
ARPPacket.arpFrame.Opcode = htons((unsigned short)arpType); // arp包类型
// 自动填充的常量
ARPPacket.dlcHeader.Ethertype = htons((unsigned short)0x0806); // DLC Header的以太网类型ARPPacket.arpFrame.HW_Type = htons((unsigned short)1); // 硬件类型
ARPPacket.arpFrame.Prot_Type = htons((unsigned short)0x0800); // 上层协议类型
ARPPacket.arpFrame.HW_Addr_Len = (unsigned char)6; // MAC地址长度
ARPPacket.arpFrame.Prot_Addr_Len = (unsigned char)4; // IP地址长度
That’s all ! ^_^
填充完毕之后,我们需要做的就是把我们的ARPPACKET结构体发送出去
2.发送ARP数据包:
我们发送ARP包就要用到winpcap的api了,具体步骤及函数是这样的,为了简单易懂,我把错误处理的地方都去掉了,详见代码
/**********************************************************************
* Name & Params::
* SendARPPacket()
* Purpose:
* 发送ARP数据包
* Remarks:
* 用的是winpcap的api函数
***********************************************************************/