ARP协议学习笔记

一、准备工作:

1、本机环境:Windows XP SP3、电信ADSL 2M家庭宽带

2、开发工具:WildPackets OmniPeek V5.1.4

                    Visual C++ 6.0

                    FlexEdit V2.3.1871

二、ARP协议概念:

1、ARP的数据结构

  1. typedef struct arphdr  
  2. {  
  3.     unsigned short  arp_hdr;  
  4.     unsigned short  arp_pro;  
  5.     unsigned char   arp_hln;  
  6.     unsigned char   arp_pln;  
  7.     unsigned short  arp_opt;  
  8.     unsigned char   arp_sha[6];  
  9.     unsigned long   arp_spa;  
  10.     unsigned char   arp_tha[6];  
  11.     unsigned long   arp_tpa;  
  12. }ARPHDR,*PARPHDR;  

2、ARP和RARP使用相同的报头结构,如图所示。
结构

  硬件类型字段:指明了发送方想知道的硬件接口类型,以太网的值为1;

  协议类型字段:指明了发送方提供的高层协议类型,IP为0800(16进制);

  硬件地址长度和协议长度:指明了硬件地址和高层协议地址的长度,这样ARP报文就可以在任意硬件和任意协议的网络中使用;

  操作字段:用来表示这个报文的类型,ARP请求为1,ARP响应为2,RARP请求为3,RARP响应为4;

  发送方的硬件地址(0-2字节):源主机硬件地址的前3个字节;

  发送方的硬件地址(3-5字节):源主机硬件地址的后3个字节;

  发送方IP(0-1字节):源主机硬件地址的前2个字节;

  发送方IP(2-3字节):源主机硬件地址的后2个字节;

  目的硬件地址(0-1字节):目的主机硬件地址的前2个字节;

  目的硬件地址(2-5字节):目的主机硬件地址的后4个字节;

  目的IP(0-3字节):目的主机的IP地址。

三、分析数据包:

1、先看ARP请求(ARP  Request):

arp request

2、再看ARP应答(ARP  Response):

ARP Response

四、相关代码:

1、下面是MSDN中实例代码,用来向指定IP地址发送ARP请求,来获取他的MAC地址:

  1. // SendARP.cpp : Defines the entry point for the console application.   
  2. // ARP 协议学习笔记   
  3. // By Koma 09:47 2009-09-12   
  4.   
  5. #include <windows.h>   
  6. #include <stdio.h>   
  7. #include <tchar.h>   
  8. #include <iphlpapi.h>   
  9.   
  10. #include <Winsock2.h>   
  11. #pragma comment(lib,"Ws2_32.lib")   
  12. #pragma comment(lib,"iphlpapi.lib")   
  13.   
  14. int main(int argc, char* argv[])  
  15. {  
  16.     HRESULT hr;  
  17.     IPAddr  ipAddr;  
  18.     ULONG   pulMac[2];  
  19.     ULONG   ulLen;  
  20.     char*   pstrIP = "192.168.1.121";  
  21.   
  22.     ipAddr  = inet_addr(pstrIP);  
  23.     ulLen   = 6;  
  24.     memset(pulMac, 0xff, sizeof (pulMac));  
  25.       
  26.     hr = SendARP (ipAddr, 0, pulMac, &ulLen);  
  27.     if(NO_ERROR == hr)  
  28.     {  
  29.         printf ("返回信息:%08x,返回长度:%8d/n", hr, ulLen);  
  30.         size_t i, j;  
  31.         char * szMac = new char[ulLen*3];  
  32.         PBYTE pbHexMac = (PBYTE) pulMac;  
  33.           
  34.         // Convert the binary MAC address into human-readable   
  35.         memset(szMac,0,sizeof(szMac));  
  36.         memset(pbHexMac,0,sizeof(pbHexMac));  
  37.   
  38.         for (i = 0, j = 0; i < ulLen - 1; ++i)  
  39.         {  
  40.             j += sprintf (szMac + j, "%02X:", pbHexMac[i]);  
  41.         }  
  42.         sprintf (szMac + j, "%02X", pbHexMac[i]);  
  43.         printf ("返回MAC地址为:%s/n", szMac);  
  44.         delete [] szMac;  
  45.     }  
  46.     else  
  47.     {   // Error.   
  48.         printf("IP地址:%s不存在,或被防火墙拦截!/n",pstrIP);  
  49.     }  
  50.     return 0;  
  51. }  

2、程序运行效果:

运行效果

原文地址:https://www.cnblogs.com/hehehaha/p/6332956.html