arp协议研究在vc6.0环境下的c语言,ARP地址解析协议实验报告.doc

网络技术与应用实验报告

实验三

目录

背景知识3

开发环境4

程序设计7

ARP数据包结构定义7

获取本机网络接口的MAC地址和IP地址9

向网络发送数据包12

程序测试15

执行结果界面截图15

执行结果分析17

获取IP地址与MAC地址的对应关系

背景知识

以太网的一个很大的特点就是具有强大的广播能力。针对这种具备广播能力、物理地址长但长度固定的网络,IP互联网采用动态联编方式进行IP地址到物理地址的映射,并制定了相应的协议——ARP。

假定在一个以太网中,主机A欲获取主机B的IP地址IB与MAC地址PB的映射关系。ARP协议的工作过程为:

1)主机A广播发送一个带有IB的请求信息包,请求主机B用它的IP地址IB和MAC地址PB的映射关系进行相应;

2)于是,以太网上的所有主机接受到这个请求信息包(包括主机B在内);

3)主机B识别该请求信息,并向主机A发送带有自己的IP地址IB和MAC地址PB映射关系的相应数据包;

4)主机A 得到IB与PB的映射关系,并可以在随后的发送过程中使用该映射关系。

当ARP报文在以太网中传送时,需要将它们封装在以太网数据帧中。为了使接收方能够容易地识别该数据帧携带的为ARP数据,发送方需要将以太网数据帧首部的长度/类型字段指定为0x0806。由于ARP请求和应答分别采用广播方式和单播方式发送,因此封装ARP请求数据帧的目的地址为全“1”形式的广播地址,而封装ARP响应的数据真的目的地址为接收节点的单播地址。在以太网中,ARP数据包的格式如图3-1所示:

硬件类型

协议类型

硬件地址长度

协议地址长度

操作

源MAC地址(0~3)

源MAC地址(4~5)

源IP地址(0~1)

源IP地址(2~3)

目的MAC地址(0~1)

目的MAC地址(2~5)

目的IP地址(0~3)

图3-1以太网中ARP的报文格式

其中,个字段的意义如下:

硬件类型:物理接口类型。其中,以太网的接口类型为1。

协议类型:高层协议类型。其中,IP协议类型为0x0800。

操作:指定ARP报文一个ARP请求还是一个ARP应答。其中,ARP请求报文为 1,ARP应答报文为2。

硬件地址长度:以字节为单位的物理地址长度。在以太网中,物理地址(MAC 地址)的长度为6B。

协议地址长度:以字节为单位的上层协议地址长度。IP地址长度为4B。

源MAC地址:发送方的MAC地址。

源IP地址:发送方的IP地址。

目的MAC地址:在ARP请求报文中,该字段内容没有意义;在ARP响应报文中, 该字段为接收方的MAC地址。

目的IP地址:在ARP请求报文中,该字段为请求解析的IP地址;在ARP响应 报文中,该字段为接收方的IP地址。

开发环境

本实验的目的是捕获以太网中的数据包并对其进行分析,因此以太网在该实验中时必不可少的。本实验使用的以太网既可以是共享式以太网也可以是交换式以太网。

本实验利用Microsoft集成开发环境IDE创建基于WinPcap的应用程序。因此,需要在源码中增加与WinPcap相关的信息,还需要对IDE中的某些缺省参数进行修改。下面介绍使用VC6.0创建基于WinPcap应用程序的配置方法:

1.添加pcap.h包含文件:如果一个源文件使用了WinPcap提供的函数,那么需要在该文件开始位置增加pcap.h包含文件,如下所示:

#include“pcap.h”

2.增加与WinPcap有关的预处理器定义:需要将WPCAP和HAVE_REMOTE两个标号添加到预处理器定义中。在VC6.0提供的IDE环境中,可以通过执行“工程”菜单中的“设置”命令进入该项目的属性配置页,如图2-2所示。通过选择“C/C++”选项就可以增加这两个标号。

图3-2在预处理器定义中增加WPCAP和HAVE_REMOTE

3.添加包含文件目录:在生成基于WinPcap的应用程序过程中,生成程序需要知道pcap.h等包含文件在磁盘中的位置,因此需要将WinPcap提供的包含文件目录位置通知生成程序。添加包含文件目录可以通过执行“工具”菜单中的“选项”命令进入“选项”对话框,如图2-3所示。然后,通过选择对话框中的“目录->include files”选项可以将WinPcap的包含文件目录添加到IDE集成开发环境中。

图3-3在IDE集成开发环境中增加包含文件目录

4.添加wpcap.lib库文件:在生成基于WinPcap的应用程序过程中,生成程序需要链接wpcap.lib库文件。因此,需要将WinPcap.lib添加到利用IDE集成开发环境生成的项目中。添加wpcap.lib库文件可以通过执行“项目”菜单中的“设置”命令进入“Project Settings”对话框,如图2-4所示。通过选择“连接”选项就可以添加wpcap.lib库文件。

图3-4添加wpcap.lib库文件

程序设计

利用WinPcap获取IP地址与MAC地址的对应关系需要经过下面各步骤。

ARP数据包结构定义

网络中传输的数据包是经过封装的,每一次封装都会增加相应的首部。由于WinPcap在数据链路层捕获数据包,因此在以太网中利用pcap_next_ex函数获得的数据都包含以太网帧头信息。同时,由于利用pcap_next_ex函数捕获到的数据包保存在一个无结构的缓冲区中,因此在实际编程过程中,通常需要定义一些有关首部的数据结构,通过将这些结构赋予存放数据包的无结构缓冲区简化数据的提取过程。

在分析以太网数据帧和ARP数据包时可以定义以太网数据帧和ARP数据包首部结构为:

#pragma pack(1)//进入字节对齐模式

typedef struct FrameHeader_t{//帧头部

BYTE DesMac[6]; //目的地址

BYTE SrcMac[6]; //源地址

WORD FrameType; //帧类型

}FrameHeader_t;

typedef struct ARPFrame_t{//IP首部

FrameHeader_t FrameHeader;

WORD HardwareType;

WORD ProtocolType;

BYTE HLen;

BYTE PLen;

WORD Operation;

BYTE SendHa[6];

DWORD SendIP;

BYTE RecvHa[6];

DWORD RecvIP;

}ARPFrame_t;

typedef struct Data_t{//包含帧首部和IP首部的数据包

FrameHeader_t FrameHeader;

IPHeader_t IPHeader;

}Data_t;

#pragma pack()//恢复缺省对齐模式

获取本机网络接口的MAC地址和IP地址

调用WinPcap的pcap_findalldevs_ex函数后,参数alldevs指向的链表中包含了主机中安装的网络接口设备列表。在alldevs链表中每个元素保存的网络接口相关信息中,地址信息保存了该网络接口上绑定的IP地址、网络掩码、广播地址和目的地址等。由于每个网络接口卡上可以绑定多个IP地址,因此每个网络接口卡拥有的地址信息也采用了链表结构,其具体定义如下:

typedef struct pcap_ifpcap_if_t;

structpcap_if{

struct pcap_if *next;

char *name;

char *description;

struct pcap_addr *addresses;

u_int flags;

};

struct pcap_addr{

struct pcap_addr *next;

struct sockaddr *addr;

struct sockaddr *netmask;

struct sockaddr *broadaddr;

struct sockaddr *dstaddr;

};

实验中按照上面的链表结构,利用WinPcap的pcap_findalldevs_ex获取本机的网络接口卡及其每块网卡上绑定的IP地址的程序代码如下:

pcap_if_t *alldevs;//指向设备链表首部的指针

pcap_if_t *d

pcap_addr_t *a

char errbuf[PCAP_ERRBUF_SIZE];//错误信息缓冲区

//获得本机的设备链表

if(pcap_findalldevs_ex(PCAP_SRC_IF_STRING,NULL,&alldevs,errbuf)==-1)

{

MessageBox(“无法获取设备链表”);

}

for(a=d->addresses;a!=NULL;a=a->next)

{

if(a->addr->sa_family==AF_INET)//判断该地址是否为IP地址

{

//利用a->addr获取IP地址

str.Format("%d.%d.%d.%d",

(BYTE)a->addr->sa_data[2],(BYTE)a->addr->sa_data[3],

(BYTE)a->addr->sa_data[4],(BYTE)a->addr->sa_data[5]);

m_details.InsertString(-1,str);

//利用a->addr获取网络掩码

str.Format("%d.%d.%d.%d",

(BYTE)a->netmask->sa_data[2],(BYTE)a->netmask->sa_data[3],

(BYTE)a->netmask->sa_data[4],(BYTE)a->netmask->sa_data[5]);

m_details.InsertString(-1,str);

}

为了形成ARP请求数据包,不但需要知道本机网络接口上绑定的IP地址,而且必须知道这块网卡的MAC地址。在理解ARP协议的基本思想后,可以直接通过WinPcap获取本机网络接口的MAC地址。

按照ARP协议,以太网中的主机如果发现一个ARP所请求的IP地址为自己拥有的IP地址,那么它将形成ARP响应并将该IP地址与MAC地址的对应关系返回给请求主机。如果应用程序能够捕获到本机发出的ARP响应,那么就能够知道本机网络接口的MAC地址。按照这种原理,利用WinPcap获得本机网络接口MAC地址和IP地址的过程大致如下:

1)获取本机安装的网络接口和接口上绑定的IP地址:利用WinPcap提供的pcap_findalldevs_ex函数获取本机的接口设备列表,从而获得本机网络接口及其接口上绑定的IP地址。

2)发送ARP请求,请求本机网络接口上绑定的IP地址与MAC地址的对应关系:本地主机模拟一个远端主机,发送一个ARP请求报文,该请求报文请求本机网络接口上绑定的IP地址与MAC地址的对应关系。在组装报文过程中,源MAC地址字段和源IP地址字段需要使用虚假的MAC地址和虚假的IP地址。本地主机一旦获取该ARP请求就会做出响应。

3)应用程序捕获本机的ARP响应,获取本机网络接口卡的MAC地址:利用WinPcap捕获本机的ARP响应,从而得到本机网络接口卡的MAC地址。

在得到本机网络接口的MAC地址和其上绑定的IP地址后,应用程序就可以组装和发送ARP请求报文,请求以太网中其他主机的IP地址与MAC地址的对应关系。

实验中运用以下程序段获取本机网络接口的MAC地址和其上绑定的IP地址:

//封装ARP请求包

for(i=0;i<6;i++)

{

ARPFrameSent.FrameHeader.DesMAC[i]=0xff;

//目的MAC地址设置为广播地址

ARPFrameSent.FrameHeader.SrcMAC[i]=0x66;

ARPFrameSent.SendHa[i]=0x66;

ARPFrameSent.RecvHa[i]=0x00;

}

ARPFrameSent.FrameHeader.FrameType=htons(0x0806);

ARPFrameSent.HardwareType=htons(0x0001);

ARPFrameSent.HLen=6;

ARPFrameSent.PLen=4;

ARPFrameSent.Operation=htons(0x0001);

ARPFrameSent.SendIP=inet_addr(“112.112.112.112”);

//目的IP地址设置为本机网卡上绑定的IP地址

ARPFrameSent.SendIP=htonl(

((BYTE)a->addr->sa_data[2]<<24)+((BYTE)a->addr->sa_data[3]<<16)

+((BYTE)a->addr->sa_data[4]<<8)+((BYTE)a->addr->sa_data[5]));

//启动数据包捕获者线程

m_Capturer=AfxBeginThread(Capturer,NULL,THREAD_PRIORITY_NORMAL);

int start=clock(); //启动计时器

while(DstMACGot!=TRUE&&clock()-start<=30000)

{

pcap_sendpacket(p,(u_char *)&ARPFrameSent,sizeof(ARPFrameSent));

}

if(DstMACGot!=TRUE) //在规定时间内未捕获IP地址与MAC地址对应关系

{

MessageBox("请求超时");

}

else

{

//输出IP地址与MAC地址对应关系

CString str;

str.Format("%s->%02x-%02x-%02x-%02x-%02x-%02x",

m_strDesIP,

ARPFrameReceived->FrameHeader.SrcMAC[0],

ARPFrameReceived->FrameHeader.SrcMAC[1],

ARPFrameReceived->FrameHeader.SrcMAC[2],

ARPFrameReceived->FrameHeader.SrcMAC[3],

ARPFrameReceived->FrameHeader.SrcMAC[4],

ARPFrameReceived->FrameHeader.SrcMAC[5]);

m_match.InsertString(-1,str);

}

向网络发送数据包

为了获取以太网中其他主机的IP地址与MAC地址的对应关系,应用程序需要向以太网广播ARP请求。向以太网发送数据报可以使用WinPcap提供的pcap_sendpacket()函数,该函数原型如下:

Int pcap_send_packet(

pcap_t *p,

u_charbuf,

int size

);

其中,pcap_sendpacket函数中各参数的意义如下:

p:指定pcap_sendpacket函数通过哪块接口网卡发送数据包。该参数为一个指向pcap_t结构的指针,通常是调用pcap_open函数成功后返回的值。

buf:指向需要发送的数据包,该数据包应该包含各层的头部信息。但需要注意的是,以太帧的CRC校验和字段不应该包含在buf中,WinPcap在发送过程中会自动为其添加校验和。

size:指定发送数据包的大小。

在发送成功后时,pcap_sendpacket函数返回0,后则返回-1.

实验中,利用WinPcap发送ARP请求的程序如下:

//封装ARP请求包

for(i=0;i<6;i++)

{

//将目的MAC地址设置为广播地址

ARPFrameSent.FrameHeader.DesMAC[i]=0xff;

//将源MAC地址设置为本机网卡的MAC地址

ARPFrameSent.FrameHeader.SrcMAC[i]=SrcMACAddr[i];

ARPFrameSent.SendHa[i]=SrcMACAddr[i];

ARPFrameSent.RecvHa[i]=0x00;

}

//帧类型为ARP

ARPFrameSent.FrameHeader.FrameType=htons(0x0806);

//硬件类型为以太网

ARPFrameSent.HardwareType=htons(0x0001);

//协议类型为IP

ARPFrameSent.ProtocolType=htons(0x0800);

//硬件地址长度为6

ARPFrameSent.HLen=6;

//协议地址长度为4

ARPFrameSent.PLen=4;

//操作为ARP请求

ARPFrameSent.Operation=htons(0x0001);

//源IP地址设置为本机网卡上绑定的IP地址

ARPFrameSent.SendIP=htonl(

((BYTE)a->addr->sa_data[2]<<24)+((BYTE)a->addr->sa_data[3]<<16)

+((BYTE)a->addr->sa_data[4]<<8)+((BYTE)a->addr->sa_data[5]));

//目的IP地址设置为请求的IP地址

ARPFrameSent.RecvIP=htonl(DstIP);

//启动数据包捕获者线程

m_Capturer=

AfxBeginThread(Capturer,NULL,THREAD_PRIORITY_NORMAL);

int start=clock(); //启动计时器

while(DstMACGot!=TRUE&&clock()-start<=30000)

{

pcap_sendpacket(p,(u_char *)&ARPFrameSent,sizeof(ARPFrameSent));

}

if(DstMACGot!=TRUE) //在规定时间内未捕获IP地址与MAC地址对应关系

{

MessageBox("请求超时");

}

else

{

//输出IP地址与MAC地址对应关系

CString str;

str.Format("%s->%02x-%02x-%02x-%02x-%02x-%02x",

m_strDesIP,

ARPFrameReceived->FrameHeader.SrcMAC[0],

ARPFrameReceived->FrameHeader.SrcMAC[1],

ARPFrameReceived->FrameHeader.SrcMAC[2],

ARPFrameReceived->FrameHeader.SrcMAC[3],

ARPFrameReceived->FrameHeader.SrcMAC[4],

ARPFrameReceived->FrameHeader.SrcMAC[5]);

m_match.InsertString(-1,str);

}

}

程序测试

执行结果界面截图

1.程序运行后的初始界面如图3-5所示,列表了显示本机的全部网络设备接口。

图3-5程序初始界面

2.选择感兴趣的网络设备接口,单击“确定”按钮,则可获得所选接口的详细信息通过该接口发送ARP数据包,如图3-6所示。

图3-6获取指定网络接口的详细信息及其上绑定的IP地址

3.在编辑框中输入请求的IP地址,并单击“获取”按钮,程序首先对输入的IP地址进行合法性判断,若输入的不是有效IP地址时提示用户(如图3-7所示)。

图3-7 输入的IP地址不合法

4.输入合法IP地址并单击“获取”按钮后,若在规定时间内(实验中将该期间设置为30秒)成功获取IP地址与MAC地址对应关系,则将该对应关系显示在列表框中(如图3-8所示),否则,弹出“请求超时”提示框(如图3-9)所示。

图3-8 成功获取IP地址与MAC地址对应关系

图3-9 在规定时间内未获得IP地址与MAC地址对应关系

执行结果分析

通过对程序运行结果的分析发现,用户只能获得与运行该程序的主机处于同一物理网络中的主机上的IP地址与其MAC地址的对应关系。

18

展开阅读全文

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值