手把手教你玩转ARP包(三)【数据包的游戏系列之一】

类别:VC语言 点击:0 评论:0 推荐:
作者: CSDN  VC/MFC 网络编程 PiggyXP  ^_^     目录: 二。发送数据包的编程实现    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.Targ_HW_Addr); // 目的MAC      ARPPacket.arpFrame.Targ_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函数 ***********************************************************************/ 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")了。           整个项目其实可以分为四个部分,填充数据包、发送数据包、枚举系统网卡列表和 相关信息以及枚举系统ARP缓存列表,下面我再讲一下如何获得系统的网卡以及ARP列 表,这两个部分都要用到IP Helper的api,所以要包含<Iphlpapi.h>以及库文件Iphlpapi.lib, 其实都是很简单的,只用寥寥几行就OK了 2.     枚举系统网卡以及信息 最好是先定义关于网卡信息的一个结构体,这样显得结构比较清晰 // 网卡信息 typedef struct tagAdapterInfo          {               char szDeviceName[128];           // 名字               char szIPAddrStr[16];             // IP               char szHWAddrStr[18];             // MAC               DWORD dwIndex;                    // 编号          }INFO_ADAPTER, *PINFO_ADAPTER;   /********************************************************************* *    Name & Params:: *             AddAdapInfoToList *             ( *                  CListCtrl& list :  CARPPlayerDlg传入的list句柄 *             ) *    Purpose: *             获得系统的网卡信息,并将其添加到list控件中 *    Remarks: *             获得网卡IP及MAC用到了IpHelper api GetAdaptersInfo ******************************************************************/ void AddAdapInfoToList(CListCtrl& list) {      char tempChar;      ULONG uListSize=1;      PIP_ADAPTER_INFO pAdapter;           // 定义PIP_ADAPTER_INFO结构存储网卡信息      int nAdapterIndex = 0;        DWORD dwRet = GetAdaptersInfo((PIP_ADAPTER_INFO)&tempChar, &uListSize);//关键函数        if (dwRet == ERROR_BUFFER_OVERFLOW)      {   PIP_ADAPTER_INFO pAdapterListBuffer = (PIP_ADAPTER_INFO)new(char[uListSize]);   dwRet = GetAdaptersInfo(pAdapterListBuffer, &uListSize);   if (dwRet == ERROR_SUCCESS)   {      pAdapter = pAdapterListBuffer;      while (pAdapter)                                              // 枚举网卡然后将相关条目添加到List中      {         // 网卡名字           CString strTemp = pAdapter->AdapterName;                               strTemp = "\\Device\\NPF_" + strTemp;                        // 加上前缀           list.InsertItem(nAdapterIndex,strTemp);                            strcpy(AdapterList[nAdapterIndex].szDeviceName,strTemp);           // IP           strcpy(AdapterList[nAdapterIndex].szIPAddrStr,                                                  pAdapter->IpAddressList.IpAddress.String );           list.SetItemText(nAdapterIndex,1,AdapterList[nAdapterIndex].szIPAddrStr);           // MAC           formatMACToStr( AdapterList[nAdapterIndex].szHWAddrStr, pAdapter->Address );           list.SetItemText(nAdapterIndex,2,AdapterLis[nAdapterIndex].szHWAddrStr);           // 网卡编号           AdapterList[nAdapterIndex].dwIndex = pAdapter->Index;                      pAdapter = pAdapter->Next;           nAdapterIndex ++;           }      delete pAdapterListBuffer;      } } }   2)获取ARP条目列表 // ARP条目信息 typedef struct tagARPInfo             {      char szIPAddrStr[16];              // IP      char szHWAddrStr[18];             // MAC      DWORD dwType;                     // 类型 }INFO_ARP, *PINFO_ARP;     /********************************************************************** *    Name & Params:: *             AddARPInfoToList *             ( *                  CListCtrl& list :             CARPPlayerDlg传入的list句柄 *                  const short nAdapterIndex :   用户选中的网卡编号 *             ) *    Purpose: *             读入系统的ARP缓存列表,.并添加到对话框中 *    Remarks: *             用到了IpHelper api GetIpNetTable *             而且用到了WinSock的api,所以要包含<WinSock2.h> *****************************************************************/ void AddARPInfoToList(CListCtrl& list,const short nAdapterIndex) {      char tempChar;      DWORD dwListSize = 1;      DWORD dwRet;      in_addr inaddr;      list.DeleteAllItems();        dwRet = GetIpNetTable((PMIB_IPNETTABLE)&tempChar, &dwListSize, TRUE);  // 关键函数      if (dwRet == ERROR_INSUFFICIENT_BUFFER)      {          PMIB_IPNETTABLE pIpNetTable = (PMIB_IPNETTABLE)new(char[dwListSize]);          dwRet = GetIpNetTable(pIpNetTable, &dwListSize, TRUE);          if (dwRet == ERROR_SUCCESS)          {               for (int i=0; i<(int)pIpNetTable->dwNumEntries; i++)               {                   // IP                    inaddr.S_un.S_addr = pIpNetTable->table[i].dwAddr;                    strcpy( ARPList[i].szIPAddrStr, inet_ntoa(inaddr) );                      // MAC                    formatMACToStr( ARPList[i].szHWAddrStr, pIpNetTable->table[i].bPhysAddr );                    // Type                    ARPList[i].dwType = pIpNetTable->table[i].dwType;                              if (AdapterList[nAdapterIndex].dwIndex != pIpNetTable->table[i].dwIndex)                                                       continue;                      list.InsertItem(i,ARPList[i].szIPAddrStr);                    list.SetItemText(i,1,ARPList[i].szHWAddrStr);                    switch(ARPList[i].dwType) {           // 根据type的值来转换成字符显示                    case 3:                        list.SetItemText(i,2,"Dynamic");                        break;                    case 4:                        list.SetItemText(i,2,"Static");                        break;                    case 1:                        list.SetItemText(i,2,"Invalid");                    default:                        list.SetItemText(i,2,"Other");                    }               }          }          delete pIpNetTable;      } }         这样一来,我们基本上大功告成了,其他还有一些东西在这里就不讲了,大家可以下载我的代码看看就好了。         下面我们来用ARP包玩一些小把戏 ^_^。         (未完待续)        。。。。。。。。。。。。。。。。 =======================================================================     本篇前两部分地址:    手把手教你玩转ARP包(上)   http://www.csdn.net/Develop/read_article.asp?id=28419    手把手教你玩转ARP包(中上)    http://www.csdn.net/develop/article/28/28421.shtm                                                                          ------    Finished at  2004-05-30 14:41

                                                                                        -------    Made In     DLUT | DIP

   

本文地址:http://com.8s8s.com/it/it881.htm