当前位置:文档之家› 捕获数据包

捕获数据包

希望通过这一系列的文章,能使得关于数据包的知识得以普及,所以这系列的每一篇文章我都会有由浅入深的解释、详细的分析、以及编码步骤,另外附上带有详细注释的源码文章作者: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中使用winpcap2. 获得网卡信息列表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);// 源MACARPPacket.arpFrame.Send_Prot_Addr = inet_addr(srcIP); // 源IPformatStrToMAC(“ARP目的MAC字符串”,ARPPacket.arpFrame.T arg_HW_Addr); // 目的MAC ARPPacket.arpFrame.T arg_Prot_Addr = inet_addr(desIP); // 目的IPARPPacket.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函数***********************************************************************/void SendARPPacket(){char *AdapterDeviceName =GetCurAdapterName(); // 首先获得获得网卡名字lpAdapter = PacketOpenAdapter(AdapterDeviceName); // 根据网卡名字打开网卡lpPacket = PacketAllocatePacket(); // 给PACKET结构指针分配内存PacketInitPacket(lpPacket, &ARPPacket, sizeof(ARPPacket)); //初始化PACKET结构指针// 其中的ARPPacket就是我们先前填充的ARP包PacketSetNumWrites(lpAdapter, 1); // 每次只发送一个包PacketSendPacket(lpAdapter, lpPacket, true) // Send !!!!! ^_^PacketFreePacket(lpPacket); // 释放资源PacketCloseAdapter(lpAdapter);}呵呵,至此,关于ARP包最关键的部分就讲完了,你现在就可以来随心所欲的发送自己的ARP包了既然作为一篇“科普文章”,接下来我再讲一讲与整个项目有关的附加步骤以及说明三.附加步骤以及说明1. 如何在VC中使用winpcap驱动虽然winpcap开发包使用起来非常简便,但是前期准备工作还是要费一番功夫的,缺一不可。

^_^首先就是要安装它的驱动程序了,可以到它的主页下载,更新很快的http://winpcap.polito.it/install/default.htm下载WinPcap auto-installer (driver +DLLs),直接安装就好了,或者我提供的代码包里面也有。

希望以后用winpcap作开发的朋友,还需要下载Developer's pack,解压即可。

然后,需要设置我们工程的附加包含目录为我们下载Developer's pack开发包的Inclulde目录,连接器的附加依赖库设置为Developer's pack的lib目录。

当然,因为我们的工作比较简单,就是借用winpcap发送数据包而已,所以只用从winpcap开发包的include文件夹中,拷贝Packet32.h,到我们的工程来,并且包含它就可以,但是要注意,Packet32.h本身还要包含一个Devioctl.h,也要一并拷贝进来,当然还有运行库Packet.lib,一共就是需要拷贝3个文件了,如果加入库不用我多说了吧,在工程里面设置,或者是在需要它的地方加入#pragma comment(lib, "Packet.lib")了。

相关主题