发送EthernetARP数据包.docx
《发送EthernetARP数据包.docx》由会员分享,可在线阅读,更多相关《发送EthernetARP数据包.docx(13页珍藏版)》请在冰豆网上搜索。
发送EthernetARP数据包
计算机网络基础课程设计报告
题目:
发送EthernetARP
学生姓名:
学号:
专业班级:
同组姓名:
指导教师:
设计时间:
2011年下学期第18周
指导老师意见:
评定成绩:
签名:
日期:
2012年1月5日
一、课程设计的目的和意义
IP地址将不同的物理地址统一起来,从而将物理地址隐藏起来,上层软件使用IP地址标识结点。
但是。
两台计算机只有在知道彼此的物理地址时才能进行通信。
IP数据包常通过Ethernet发送。
Ethernet设备并不识别32位IP地址,它们是以48位MAC地址传输Ethernet数据包的。
因此,IP驱动器必须把IP目的地址转换成Ethernet网络目的地址。
这两种地址之间存在着某种静态的或动态的映射,通常需要查看一张表来进行这种映射。
这种地址协议(ARP)就是用来确定这些映象的协议。
ARP工作时,送出一个所希望的IP地址的Ethernet广播数据包。
目的地主机以一个含有IP和Ethernet地址对的数据包作为应答。
发送者将这个地址对高速缓存起来,以节约不必要的ARP通信。
本课程设计的目的是进一步熟悉ARP协议的帧结构以及它的运行过程
二、设计的内容和要求
基本要求
本次课程设计的基本要求是在熟悉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应答。
例如:
arpsendFA:
01:
02:
03:
04:
050D:
E1:
02:
03:
B4:
061
2)输出:
SendOK。
3)程序的正确性的检验。
可以安装一个截包软件,如Iris,运行该软件以查看能否收到程序发出的ARP包,并检查包中个字段填充的内容(如各地址,协议类型)是否正确。
Error!
Nobookmarknamegiven.2.2系统开发语言及环境的选择
操作系统:
WindowsXPProfessional
运行环境:
MicrosoftVisualC++
开发语言:
C语言,C++等
三、设计的相关技术
ARP协议及工作原理
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帧结构
工作原理:
源主机在传输数据前,首先要对初始数据进行封装,在该过程中会把目的主机的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。
四、程设计过程
流程图
图5程序流程图
源程序
#include<>
#include<>
#pragmacomment(lib,"")
#include""
main(intargc,char**argv)
{
u_charpacket[100];
pcap_if_t*alldevs;
pcap_if_t*d;
intinum;
inti=0,j,k,temp[4];
pcap_t*adhandle;
charerrbuf[PCAP_ERRBUF_SIZE];
/*获取设备列表*/
if(argc!
=6)
{
printf("使用:
%s接口",argv[0]);
return-1;
}
if(pcap_findalldevs(&alldevs,errbuf)==-1)
{
fprintf(stderr,"pcap_findalldevs错误:
%s\n",errbuf);
exit
(1);
}
/*数据列表*/
for(d=alldevs;d;d=d->next)
{
printf("%d.%s",++i,d->name);
if(d->description)
printf("(%s)\n",d->description);
else
printf("(没有可用的描述)\n");
}
if(i==0)
{
printf("\n没有发现接口!
请确保安装winpcap。
\n");
return-1;
}
printf("输入接口号码(1-%d):
",i);
scanf("%d",&inum);
if(inum<1||inum>i)
{
printf("\n接口号码超过范围.\n");
/*释放设备列表*/
pcap_freealldevs(alldevs);
return-1;
}
/*转到选择的设备*/
for(d=alldevs,i=0;inext,i++);
/*打开设备*/
if((adhandle=pcap_open_live(d->name,%s不支持WinPcap\n");
/*释放列表*/
pcap_freealldevs(alldevs);
return-1;
}
/*我们已经不需要设备列表了,释放它*/
pcap_freealldevs(alldevs);
/*填充数据段*/
;j=j+temp[3])
{
temp[0]=0;
temp[1]=0;
temp[2]=0;
temp[3]=0;
for(i=0;i<4&&temp[2]==0;i++)
{
if(argv[1][j+i]>='0'&&argv[1][j+i]<='9')
{
temp[0]=(int)argv[1][j+i]-48;
temp[1]=temp[1]*10+temp[0];
}
else
temp[2]=1;
temp[3]++;
}
packet[28+k]=temp[1];
k++;
}
;j=j+temp[3])
{
temp[0]=0;
temp[1]=0;
temp[2]=0;
temp[3]=0;
for(i=0;i<4&&temp[2]==0;i++)
{
if(argv[3][j+i]>='0'&&argv[3][j+i]<='9')
{
temp[0]=(int)argv[3][j+i]-48;
temp[1]=temp[1]*10+temp[0];
}
else
temp[2]=1;
temp[3]++;
}
packet[38+k]=temp[1];
k++;
}
packet[12]=0x08;
packet[13]=0x06;
packet[14]=0x00;
packet[15]=0x01;
packet[16]=0x08;
packet[17]=0x00;
packet[18]=0x06;
packet[19]=0x04;
packet[20]=0x00;
packet[21]=(int)argv[5][0]-47;
/*填充发送包的剩余部分*/
for(i=0;i<22;i++)
{
packet[42+i]=0;
}
/*发送包*/
pcap_sendpacket(adhandle,packet,64);
printf("\n发送成功\n");
return0;
}
运行结果
1.应该在预编译代码区加上预编译指令:
#pragmacomment(lib,"");
否则,链接时会出现符号无法解析的错误。
2.程序中填充DLC头中帧类型应该是:
=htons((unsignedshort)0x0806);而实验所给的代码却是:
=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截获的包
五、课程设计小结
这次课程设计让我受益匪浅。
通过对C语言和C++的学习,对编程有了一定的了解。
但学完后,我也只能是纸上谈兵,真正动起手来,还是茫然不知所措。
这次程设计就给了我们一次很好的机会,在同组人员的互相帮助下,我们将所学的编程语言与计算机网络联系,,进一步熟悉了ARP协议的帧结构以及它的运行过程。
ARP工作时,送出一个所希望的IP地址的Ethernet广播数据包,目的地主机以一个含有IP和Ethernet地址对的数据包作为应答。
通过相关扩展,熟悉了基于ARP欺骗的监听,如果某台计算机C和计算机A、B位于同一个局域网中,可以用C来监听A和B之间的通信,具体操作如下:
C给A发送一个伪造的ARP回应包,告诉A,B的IP对应的MAC为C的MAC地址,于是A就会相应地刷新自己的ARO缓存,将发给B的数据都发送到主机C上来,这样C就实现了欺骗和监听。
很感谢这次的课程设计,它使我更加深刻地体会到多看专业书的重要性,只有掌握了一定量的专业知识才能得心应手地解决诸多问题;另外,做任何事都要有耐心,不要一遇到困难就退缩;在学习和工作中要时刻谨记“认真字,它好比通向成功的铺路石,不可或缺。
课程设计之前,我总感觉自己学的还不错,但是,这次课程设计之后,我才真正看到自己知识的漏洞与不足,任何事情都只怕“认真”二字,付出了百分百,就能得到百分百,这是我最大的收获。
六、参考文献
[1]郭国强等.计算机网络与Internet教程(第二版)[M].北京:
清华大学出版社.2003
[2]谢希仁.计算机网络[M].北京:
电子工业出版社.2007
[3]胡金初.计算机网络[M].北京:
清华大学出版社.2005