发送Ethernet+ARP数据包.docx

上传人:b****6 文档编号:9002658 上传时间:2023-02-02 格式:DOCX 页数:18 大小:267.87KB
下载 相关 举报
发送Ethernet+ARP数据包.docx_第1页
第1页 / 共18页
发送Ethernet+ARP数据包.docx_第2页
第2页 / 共18页
发送Ethernet+ARP数据包.docx_第3页
第3页 / 共18页
发送Ethernet+ARP数据包.docx_第4页
第4页 / 共18页
发送Ethernet+ARP数据包.docx_第5页
第5页 / 共18页
点击查看更多>>
下载资源
资源描述

发送Ethernet+ARP数据包.docx

《发送Ethernet+ARP数据包.docx》由会员分享,可在线阅读,更多相关《发送Ethernet+ARP数据包.docx(18页珍藏版)》请在冰豆网上搜索。

发送Ethernet+ARP数据包.docx

发送Ethernet+ARP数据包

《计算机网络》课程设计

实验报告

题目发送EthernetARP包

学院数理与信息工程学院

专业计算机科学与技术

班级计科101

学号201059225101

学生姓名王立娟

同组成员潘明越、曾兵、田胜杰、宋炼杰、陈坦、韦国挺

指导教师郭步

编写日期2012-6-30

3.3工作原理………………………………………………………4

3.4ARP包的填充…………………………………………………6

4.1流程图…………………………………………………………7

4.2源程序…………………………………………………………8

4.3运行结果………………………………………………………18

六、参考文献………………………………………………………19

 

一、程设计的目的和意义

IP地址将不同的物理地址统一起来,从而将物理地址隐藏起来,上层软件使用IP地址标识结点。

但是。

两台计算机只有在知道彼此的物理地址时才能进行通信。

IP数据包常通过Ethernet发送。

Ethernet设备并不识别32位IP地址,它们是以48位MAC地址传输Ethernet数据包的。

因此,IP驱动器必须把IP目的地址转换成Ethernet网络目的地址。

这两种地址之间存在着某种静态的或动态的映射,通常需要查看一张表来进行这种映射。

这种地址协议(ARP)就是用来确定这些映象的协议。

ARP工作时,送出一个所希望的IP地址的Ethernet广播数据包。

目的地主机以一个含有IP和Ethernet地址对的数据包作为应答。

发送者将这个地址对高速缓存起来,以节约不必要的ARP通信。

本课程设计的目的是进一步熟悉ARP协议的帧结构以及它的运行过程。

二、设计的内容和要求

2.1基本要求

本次课程设计的基本要求是在熟悉ARP协议并了解Winpcap编程,或者下载JAVA类:

jpcap包构造ARP包,选择并打开网卡,将ARP包发送。

1)命令行格式:

arpsendsrc_ipsrc_macdst_ipdst_macflag

其中arpsend作为程序名。

各参数意义:

src_ip:

源IP地址。

src_mac:

源MAC地址。

dst_ip:

目的IP地址。

dst_mac:

目的MAC地址。

Flag:

0表示ARP请求;1表示ARP应答。

例如:

arpsend192.168.1.1FA:

01:

02:

03:

04:

05192.168.1.20D:

E1:

02:

03:

B4:

061

2)输出:

SendOK。

3)程序的正确性的检验。

可以安装一个截包软件,如Iris,运行该软件以查看能否收到程序发出的ARP包,并检查包中个字段填充的内容(如各地址,协议类型)是否正确。

2.2系统开发语言及环境的选择

操作系统:

WindowsXPProfessional

运行环境:

MicrosoftVisualC++6.0

开发语言:

C语言,C++等

三、设计的相关技术

3.1ARP协议及工作原理

ARP协议是“AddressResolutionProtocol”(地址解析协议)的缩写。

在局域网中,网络中实际传输的是“帧”,帧里面是有目标主机的MAC地址的。

在以太网中,一个主机要和另一个主机进行直接通信,必须要知道目标主机的MAC地址。

但这个目标MAC地址是如何获得的呢?

它就是通过地址解析协议获得的。

所谓“地址解析”就是主机在发送帧前将目标IP地址转换成目标MAC地址的过程。

ARP协议的基本功能就是通过目标设备的IP地址,查询目标设备的MAC地址,以保证通信的顺利进行。

ARP的基本运行过程是:

1)主机A希望发送数据分组给主机B,但不知道B的物理地址。

2)A发送广播报文,要求B主机用它的物理地址来响应。

3)网站上所有主机都接收到这个分组。

4)B识别出自己的IP地址,发送应答报文,告诉A自己的物理地址。

3.2ARP的分组格式

物理帧头(14B)

ARP帧结构(28B)

填充数据(18B)

CRC(4B)

图一ARP分组格式

目的MAC(6B)

源MAC(6B)

类型(2B)

 

图2物理帧头

08162431(位)

硬件类型(Ethernet:

0x1)

上层协议类型(IP:

0x0800)

硬件地址长度(0x6)

IP地址长度(0x4)

操作(请求:

0x1;应答:

0x2)

源MAC地址

源MAC地址

源IP地址

源IP地址

目的MAC地址

目的MAC地址

目的IP地址

图3ARP帧结构

3.3工作原理:

源主机在传输数据前,首先要对初始数据进行封装,在该过程中会把目的主机的IP地址和MAC地址封装进去。

在通信的最初阶段,我们能够知道目的主机的IP地址,而MAC地址却是未知的。

这时如果目的主机和源主机在同一个网段内,源主机会以第二层广播的方式发送ARP请求报文。

ARP请求报文中含有源主机的IP地址和MAC地址,以及目的主机的IP地址。

当该报文通过广播方式到达目的主机时,目的主机会响应该请求,并返回ARP响应报文,从而源主机可以获取目的主机的MAC地址,同样目的主机也能够获得源主机的MAC地址。

如果目的主机和源主机地址不在同一个网段内,源主机发出的IP数据包会送到交换机的默认网关,而默认网关的MAC地址同样可以通过ARP协议获取。

经过ARP协议解析IP地址之后,主机会在缓存中保存IP地址和MAC地址的映射条目,此后再进行数据交换时只要从缓存中读取映射条目即可。

ARP协议工作原理详见图4.

图4网段内ARP工作原理

关于ARP的功能,仅限于在没有安全防护的网络里。

1)如果有多个用户都在同一个网关上网,那么若要禁止机器A上网,应该怎么做呢?

就是让A得不到正确的网关的ARP映射。

可以采取如下措施:

伪装成网关,给机器A发送ARP包,该ARP的发送方为网关的IP,而MAC部分随便填一个地址;接收方正确填写A的相关信息。

2)基于ARP欺骗的监听。

如果某台计算机C和计算机A、B位于同一个局域网内,那么如何监听A和B间的通信呢?

很简单,对A说“我是B”,在对B说“我是A”。

具体的操作如下:

给A发送一个伪造的ARP回应包,告诉A,B的IP对应的MAC为C的MAC地址,于是A就会相应地刷新自己的ARP缓存,将发给B的数据都发送到主机C上来。

当然,因为ARP缓存是动态的,有超时时间,所以必须每隔一段时间就给A发送一个ARP回应包。

为了不让B发现,我们还要对每次接受到的数据包进行转发。

这样就监听了A发送给B的信息。

如果想监听B发送给A的信息,方法类似。

3.4ARP包的填充

将命令行的参数作适当的转换后填到ARP分组结构的各字段中即可。

要注意的是,填充请求包时。

因为包要在Ethernet上广播,所以,物理帧头的“目的MAC”字段要填充为FFFFFFFFFFFF;而ARP帧结构中的目的MAC可填充为任意值,因为它此时不起作用。

“填充数据”字段要填充为0。

四、程设计过程

4.1流程图

 

图5程序流程图

 

4.2源程序

#include

#include

#include

#include

#include

#include

#include

#pragmacomment(lib,"ws2_32.lib")

//DLC头

typedefstructDLCHeader

{

unsignedcharDesMAC[6];

unsignedcharSrcMAC[6];

unsignedshortEthertype;

}DLCHEADER;

//ARP桢

typedefstructARPFrame

{

unsignedshortHW_Type;

unsignedshortProt_Type;

unsignedcharHW_Addr_Len;

unsignedcharProt_Addr_Len;

unsignedshortFlag;

unsignedcharSend_HW_Addr[6];

unsignedcharSend_Prot_Addr[4];

unsignedcharTarg_HW_Addr[6];

unsignedcharTarg_Prot_Addr[4];

unsignedcharpadding[18];

}ARPFRAME;

//ARP包=DLC头+ARP桢

typedefstructARPPacket

{

DLCHeaderdlcHeader;

ARPFramearpFrame;

}*PARPPACKET;

ARPPacketARPPACKET;

//源文件.cpp

#include

#include

//#include"h.h"

inttransIP(char*,unsignedchar*);

inttransMAC(char*,unsignedchar*);

LPADAPTERlpAdapter;

LPPACKETlpPacket;

boolSend();

voidmain(intargc,char*argv[])

{

if(argc!

=6)

{

cout<<"输入格式错误"<

return;

}

inti=0;

memset(&ARPPACKET,0,sizeof(ARPPACKET));

if(*argv[5]=='0')

{

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

ARPPACKET.dlcHeader.DesMAC[i]=0xff;

ARPPACKET.arpFrame.Flag=(unsignedshort)1;

}

else

{

if(*argv[5]=='1')

{

//填充DLC头中目的MAC地址

if(!

transMAC(argv[4],ARPPACKET.dlcHeader.DesMAC))

return;

//ARP桢中flag位置2

ARPPACKET.arpFrame.Flag=(unsignedshort)0x0200;

}

else

cout<<"flag位输入错误"<

}

if(!

transMAC(argv[2],ARPPACKET.dlcHeader.SrcMAC))

return;

//填充DLC头中桢类型

ARPPACKET.dlcHeader.Ethertype=htons((unsignedshort)0x0608);

ARPPACKET.arpFrame.HW_Type=(unsignedshort)0x0100;

//(Ethernet类型)

ARPPACKET.arpFrame.Prot_Type=(unsignedshort)0x0008;

ARPPACKET.arpFrame.HW_Addr_Len=(unsignedchar)6;

ARPPACKET.arpFrame.Prot_Addr_Len=(unsignedchar)4;

if(!

transMAC(argv[2],ARPPACKET.arpFrame.Send_HW_Addr))

return;

if(!

transIP(argv[1],ARPPACKET.arpFrame.Send_Prot_Addr))

return;

if(!

transMAC(argv[4],ARPPACKET.arpFrame.Targ_HW_Addr))

return;

if(!

transIP(argv[3],ARPPACKET.arpFrame.Targ_Prot_Addr))

return;

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

ARPPACKET.arpFrame.padding[i]=0;

if(!

Send())

cout<<"发送arp包失败"<

}

inttransIP(char*argv,unsignedchar*a)

{

charip[16];

inti=0,j=0,k=0;

strcpy(ip,argv);

intm=strlen(argv);

for(i=0;i

{

if((ip[i]<'0'||ip[i]>'9')&&ip[i]!

='.')

{

cout<<"输入ip:

"<

return0;

}

else

{

if(ip[i]!

='.')j++;

else

{

k++;

if(j>3)

{

cout<<"输入ip:

"<

return0;

}

else

{j=0;}

if(k>3)

{

cout<<"输入ip:

"<

return0;

}

}

}

}

j=0;

for(i=0;i<4;i++)//填充IP地址

{

while(*(ip+j)<'0'||*(ip+j)>'9')j++;

a[i]=(unsignedchar)atoi(ip+j);

while(*(ip+j)>='0'&&*(ip+j)<='9')j++;

}

return1;

}

inttransMAC(char*argv,unsignedchar*b)

{

charmac[18];

inti=0,j=0,k=0;

strcpy(mac,argv);

intm=strlen(argv);

for(i=0;i

{

if(mac[i]<'0'||(mac[i]>':

'&&mac[i]<'A')||(mac[i]>'Z'&&mac[i]<'a')||mac[i]>'Z')

{

cout<<"输入mac:

"<

return0;

}

else

{

if(mac[i]!

=':

')j++;

else

{

k++;

if(j>2)

{

cout<<"输入mac"<

return0;

}

else

{j=0;}

if(k>5)

{

cout<<"输入mac"<

return0;

}

}

}

}

for(i=0;i<6;i++)//填充MAC地址

{

while(*(mac+j)==':

'||*(mac+j)=='-')j++;

if(*(mac+j)>='0'&&*(mac+j)<='9')

b[i]=(unsignedchar)(*(mac+j)-'0');

if(*(mac+j)>='a'&&*(mac+j)<='z')

b[i]=(unsignedchar)(*(mac+j)-'a'+10);

if(*(mac+j)>='A'&&*(mac+j)<='z')

b[i]=(unsignedchar)(*(mac+j)-'A'+10);

j++;

b[i]*=16;

if(*(mac+j)>='0'&&*(mac+j)<='9')

b[i]+=(unsignedchar)(*(mac+j)-'0');

if(*(mac+j)>='a'&&*(mac+j)<='z')

b[i]+=(unsignedchar)(*(mac+j)-'a'+10);

if(*(mac+j)>='A'&&*(mac+j)<='z')

b[i]+=(unsignedchar)(*(mac+j)-'A'+10);

j++;

}

return1;

}

 

boolSend()

{

charAdapterNameA[8192];

charAdapterNameU[2*sizeof(AdapterNameA)];

unsignedlongAdapterAlength=sizeof(AdapterNameA);

unsignedlongAdapterUlength=2*sizeof(AdapterNameA);

DWORDdwVersion=GetVersion();

DWORDdwWindowsMajorVersion=(DWORD)(LOBYTE(LOWORD(dwVersion)));

if(!

(dwVersion>=0x80000000&&dwWindowsMajorVersion>=4))

{

//WindowsNT

//获取UNICODE码网卡名列表

if(PacketGetAdapterNames(AdapterNameU,&AdapterUlength)==FALSE)

{

cout<<"无法得到网卡列表!

"<

returnFALSE;

}

//将第一个网卡名转为ASCII码

unsignedshort*pAdapterName=(unsignedshort*)AdapterNameU;

for(unsignedi=0;i

if((AdapterNameA[i]=(char)pAdapterName[i])=='\0')

break;

}

else

{

//Windows9x

//获取ASCII码网卡名列表

if(PacketGetAdapterNames(AdapterNameA,&AdapterAlength)==FALSE)

{

cout<<"无法得到网卡列表!

"<

returnFALSE;

}

}

lpAdapter=PacketOpenAdapter(AdapterNameA);

if(!

lpAdapter||lpAdapter->hFile==INVALID_HANDLE_VALUE)

{

cout<<"无法打开网卡,错误码:

"<

returnFALSE;

}

//发送帧

LPPACKETlpPacket;//分配发送包结构

if((lpPacket=PacketAllocatePacket())!

=NULL)

{

//初始化发送包结构

PacketInitPacket(lpPacket,&ARPPACKET,sizeof(ARPPACKET));

//每次只发送一个包

PacketSetNumWrites(lpAdapter,1);

//发送包

if(PacketSendPacket(lpAdapter,lpPacket,true)==1)

{

cout<<"sendok"<

}

else

{

cout<<"发送包失败"<

PacketFreePacket(lpPacket);//释放发送包结构

}

}

else

{

cout<<"分配发送包LPPACKET结构失败!

"<

}

PacketCloseAdapter(lpAdapter);

returnTRUE;

}

4.3运行结果

1.应该在预编译代码区加上预编译指令:

#pragmacomment(lib,"ws2_32.lib");

否则,链接时会出现符号无法解析的错误。

2.程序中填充DLC头中帧类型应该是:

ARPPACKET.dlcHeader.Ethertype=htons((unsignedshort)0x0806);而实验所给的代码却是:

ARPPACKET.dlcHeader.Ethertype=htons((unsignedshort)0x0608);。

而ARP报文封装在以太网帧中的帧类型字段应该是0x0806。

3.程序在inttransMAC(char*argv,unsignedchar*b)函数中,判断MAC地址的格式是否正确后,在填充MAC地址之前,应该初始化局部变量j的值,即:

j=0;。

否则,在MAC地址格式正确的情况下,j的值为2,而后面填充MAC地址的时候会把正确的MAC地址的第一个十六进制字段删除。

例如:

正确的MAC地址-11:

12:

13:

14:

15:

16在被填充后会变成12:

13:

14:

15:

16:

00。

4.在boolSend()函数中,原程序打开网卡的程序代码为:

lpAdapter=PacketOpenAdapter(AdapterNameA);。

但是在XP系统中运行该程序时,始终打不开网卡。

后经过分析,得知XP系统中的网卡名是UNICODE编码的,占2个字节,而AdapterNameA的长度是1个字节的ASCII编码方式。

后来把那句代码改为:

lpAdapter=PacketOpenAdapter(AdapterNameU);(注:

AdapterNameU的长度是2个字节)就成功打开网卡了。

5.下面是正确运行的程序(发送EthernetARP包的程序)的截图

图六在DOS窗口下运行本程序

图七用Wireshark截获的包

 

5、课程设计小结

首先,通过查资料和网上学习,对之前学习过的C语言和C++加深了学习,对编程也有了一定的了解。

进一步学习C语言和C++语言在计算机网络中的应用,本次课程设计给了我们一次很好的机会,我们小组的成员团结一致一起完成这个课程设计,我们有不同的分工,将自己那部分学懂后,我们在进行交流,大家互相帮助,每天都有计划的完成的事情,在讨论时,我们有过争吵,但是这个是我们进步的前提。

也明白了团队的力量,团队中每个人都有自己的特长,那么大家都发挥出自己的特长,那么做的就很不错了。

这次的课程设计,让我对计算机网络有了更深入的了解,现在我们接触的课程还都是理论性很强的知识,所以对于网络如何应用还没有思路,但是这次的课程设计让我对于ARP有了了解,实践方面的能力有所加强,而不是看课本,而是真正的应用到程序中,明白了ARP工作时,送出一个所希望的IP地址的Ethernet广播数据包,目的地主机以一个含有IP和Ethernet地址对的数据包作为应答。

课程设计是培养我们综合运用所学知识,发现、提出、分析和解决实际问题,锻炼实践能力,是对我们实际工作能力的具体训练和考察过程。

在课程设计过程中,我们每个组员不仅学会了很多网络知识,还懂得了团队协作的重要性,是一次非常有意义的实践活动。

 

六、参考文献

[1]郭国强等

展开阅读全文
相关资源
猜你喜欢
相关搜索

当前位置:首页 > 总结汇报 > 实习总结

copyright@ 2008-2022 冰豆网网站版权所有

经营许可证编号:鄂ICP备2022015515号-1