CSDN首页 空间 新闻 论坛 Blog 下载 读书 网摘 搜索 .NET Java 视频 接项目 求职 在线学习 买书 程序员 通知
可用分押宝游戏火热进行中... 专题改版:Java Web 专题
CSDN社区
搜索 收藏 打印 关闭
CSDN社区 >  Delphi >  Windows SDK/API

ARP包(监听、嗅探)

楼主zhuangbx220(星)2004-08-04 18:22:13 在 Delphi / Windows SDK/API 提问

哪位朋友帮忙把以下代码转成DELPHI版本:  
   
   
   
  作者:  
  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")了。 问题点数:50、回复次数:7Top

1 楼zhuangbx220(星)回复于 2004-08-04 18:22:42 得分 0

整个项目其实可以分为四个部分,填充数据包、发送数据包、枚举系统网卡列表和  
  相关信息以及枚举系统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  
   
   
  原文   Visual   C++    
  http://dev.csdn.net/develop/article/28/28419.shtm  
  http://dev.csdn.net/develop/article/28/article/28/28421.shtm  
  Top

2 楼zhuangbx220(星)回复于 2004-08-04 20:28:56 得分 0

没人帮忙啊,,,,,,自己顶一下~!Top

3 楼zhxfzhxf1(zhxfzhxf1)回复于 2004-08-04 20:37:19 得分 30

网络上有C   to   Pascal的工具Top

4 楼nzh517(沙中泥)回复于 2004-08-04 23:08:05 得分 10

markTop

5 楼zhuangbx220(星)回复于 2004-08-06 15:57:42 得分 0

??????????????????????????Top

6 楼zhuangbx220(星)回复于 2004-08-17 12:37:49 得分 0

唉~!Top

7 楼angelface(§<@#$&^%$>§)回复于 2004-08-17 13:15:01 得分 10

呵呵, 老兄,这也太长了吧,Top

相关问题

  • winpcap嗅探数据包问题!!
  • 关于数据包嗅探器的!!!急用 !!
  • 关于网络数据包的嗅探的实现,用packet32开发包的问题。
  • 关于嗅探器~
  • 嗅探器问题
  • 怎么监听收到的网络数据包?
  • 哪位监听过OICQ的UDP数据包,请进
  • 如何监听本机收到的数据包
  • 请教:如何用vb实现网络数据包监听
  • 如何监听指定进程的数据包

关键词

  • .net
  • mac
  • 结构
  • article
  • csdn
  • 信息
  • 系统
  • develop
  • pipnettable
  • arplist

得分解答快速导航

  • 帖主:zhuangbx220
  • zhxfzhxf1
  • nzh517
  • angelface

相关链接

  • Delphi类图书
  • Delphi类源码下载
  • Delphi控件下载

广告也精彩

反馈

请通过下述方式给我们反馈
反馈
提问
网站简介|广告服务|VIP资费标准|银行汇款帐号|网站地图|帮助|联系方式|诚聘英才|English|问题报告
世纪乐知(北京)网络技术有限公司 版权所有, 京 ICP 证 020026 号
北京创新乐知广告有限公司 提供技术支持
Copyright © 2000-2007, CSDN.NET, All Rights Reserved
GongshangLogo