计算机网络课程设计Word文档下载推荐.docx
《计算机网络课程设计Word文档下载推荐.docx》由会员分享,可在线阅读,更多相关《计算机网络课程设计Word文档下载推荐.docx(18页珍藏版)》请在冰点文库上搜索。
这样就存在把IP地址变换成物理地址的地址转换问题。
以以太网环境为例,为了正确地向目的主机传送报文,必须把目的主机的32位IP地址转换成为48位以太网的地址。
这就需要在互连层有一组服务将IP地址转换为相应物理地址,这组协议就是ARP协议。
2.ARP工作原理
我们以主机A(192.168.1.5)向主机B(192.168.1.1)发送数据为例。
当发送数据时,主机A会在自己的ARP缓存表中寻找是否有目标IP地址。
如果找到了,也就知道了目标MAC地址,直接把目标MAC地址写入帧里面发送就可以了;
如果在ARP缓存表中没有找到相对应的IP地址,主机A就会在网络上发送一个广播,目标MAC地址是“FF.FF.FF.FF.FF.FF”,这表示向同一网段内的所有主机发出这样的询问:
“192.168.1.1的MAC地址是什么?
”网络上其他主机并不响应ARP询问,只有主机B接收到这个帧时,才向主机A做出这样的回应:
“192.168.1.1的MAC地址是00-aa-00-62-c6-09”。
这样,主机A就知道了主机B的MAC地址,它就可以向主机B发送信息了。
同时它还更新了自己的ARP缓存表,下次再向主机B发送信息时,直接从ARP缓存表里查找就可以了。
ARP缓存表采用了老化机制,在一段时间内如果表中的某一行没有使用,就会被删除,这样可以大大减少ARP缓存表的长度,加快查询速度。
3、ARP包的填充
将命令行的参数作适当的转换后填到ARP分组结构的各字段中即可。
要注意的是,填充请求包时。
因为包要在Ethernet上广播,所以,物理帧头的“目的MAC”字段要填充为FFFFFFFFFFFF;
而ARP帧结构中的目的MAC可填充为任意值,因为它此时不起作用。
“填充数据”字段要填充为0
四、课程设计分析
1.程序流程
2.核心代码及说明
头文件:
#pragmaonce
//#include<
Iphlpapi.h>
#include<
WinSock2.h>
#include"
.\Iphlpapi.h"
.\IPRTRMIB.h"
.\IPTYPES.h"
.\IPEXPORT.h"
//#pragmacomment(lib,"
Iphlpapi.lib"
)
#pragmacomment(lib,"
ws2_32.lib"
.\\wpdpack\\Iphlpapi.lib"
#defineMAX_ADAPTER10
#defineMAX_ARP20
//网卡信息
typedefstructAdapterInfo
{
charszDeviceName[128];
//名字
charszIPAddrStr[16];
//IP
charszHWAddrStr[18];
//MAC
DWORDdwIndex;
//编号
}INFO_ADAPTER,*PINFO_ADAPTER;
//ARP条目信息
typedefstructARPInfo
//IP
DWORDdwType;
//类型
}INFO_ARP,*PINFO_ARP;
classCSysInfo
{
public:
CSysInfo(void);
~CSysInfo(void);
staticvoidAddAdapInfoToList(CListCtrl&
list);
staticvoidAddARPInfoToList(CListCtrl&
list,constshortnAdpaterIndex);
inlinestaticchar*GetCurAdapterName(constshortnAdapterIndex)//返回对应网卡名字
{
returnAdapterList[nAdapterIndex].szDeviceName;
}
staticchar*GetCurAdapterMAC(constshortnAdapterIndex);
//返回对应网卡MAC
inlinestaticchar*GetCurAdapterIP(constshortnAdapterIndex)//返回对应网卡IP
returnAdapterList[nAdapterIndex].szIPAddrStr;
staticvoidformatStrToMAC(constLPSTRlpHWAddrStr,unsignedchar*HWAddr);
//用户输入的MAC地址字符串赋给数据包结构体
private:
staticINFO_ADAPTERAdapterList[MAX_ADAPTER];
//网卡列表
staticINFO_ARPARPList[MAX_ARP];
//ARP列表
staticvoidformatMACToStr(LPSTRlpHWAddrStr,constunsignedchar*HWAddr);
};
源代码:
StdAfx.h"
SysInfo.h"
INFO_ADAPTERCSysInfo:
:
AdapterList[MAX_ADAPTER];
INFO_ARPCSysInfo:
ARPList[MAX_ARP];
CSysInfo:
CSysInfo(void)
}
~CSysInfo(void)
voidCSysInfo:
AddAdapInfoToList(CListCtrl&
list)//获得系统的网卡信息,并将其添加到list控件中
chartempChar;
ULONGuListSize=1;
PIP_ADAPTER_INFOpAdapter;
//定义PIP_ADAPTER_INFO结构存储网卡信息
intnAdapterIndex=0;
DWORDdwRet=GetAdaptersInfo((PIP_ADAPTER_INFO)&
tempChar,&
uListSize);
//关键函数,调用GetAdaptersInfo函数获取网络需求缓冲区信息,并存到uListSize中
if(dwRet==ERROR_BUFFER_OVERFLOW)//调用GetAdaptersInfo((PIP_ADAPTER_INFO)&
uListSize)成功
PIP_ADAPTER_INFOpAdapterListBuffer=(PIP_ADAPTER_INFO)new(char[uListSize]);
//给pAdapterInfo分配uListSize大小的内存空间
dwRet=GetAdaptersInfo(pAdapterListBuffer,&
//获取网络信息,并存储到pAdapterListBuffer
if(dwRet==ERROR_SUCCESS)//调用GetAdaptersInfo(pAdapterInfo,&
uListSize)函数成功
{
pAdapter=pAdapterListBuffer;
while(pAdapter)//枚举网卡,然后将相关条目添加到List中
{
CStringstrTemp=pAdapter->
AdapterName;
//网卡名字
strTemp="
\\Device\\NPF_"
+strTemp;
//加上前缀
list.InsertItem(nAdapterIndex,strTemp);
strcpy(AdapterList[nAdapterIndex].szDeviceName,strTemp);
strcpy(AdapterList[nAdapterIndex].szIPAddrStr,pAdapter->
IpAddressList.IpAddress.String);
//IP
list.SetItemText(nAdapterIndex,1,AdapterList[nAdapterIndex].szIPAddrStr);
formatMACToStr(AdapterList[nAdapterIndex].szHWAddrStr,pAdapter->
Address);
list.SetItemText(nAdapterIndex,2,AdapterList[nAdapterIndex].szHWAddrStr);
AdapterList[nAdapterIndex].dwIndex=pAdapter->
Index;
//编号
pAdapter=pAdapter->
Next;
nAdapterIndex++;
}
deletepAdapterListBuffer;
//释放缓冲区内存空间
}
AddARPInfoToList(CListCtrl&
list,constshortnAdapterIndex)//读入系统的ARP缓存列表,并添加到对话框中
//用到了IpHelperapiGetIpNetTable而且用到了WinSock的api,所以要包含<
DWORDdwListSize=1;
DWORDdwRet;
in_addrinaddr;
list.DeleteAllItems();
dwRet=GetIpNetTable((PMIB_IPNETTABLE)&
dwListSize,TRUE);
//关键函数IPHelperAPIGetIpNetTable函数能够提取出本机上的所有ARP表项
if(dwRet==ERROR_INSUFFICIENT_BUFFER)
PMIB_IPNETTABLEpIpNetTable=(PMIB_IPNETTABLE)new(char[dwListSize]);
//分配内存空间
dwRet=GetIpNetTable(pIpNetTable,&
if(dwRet==ERROR_SUCCESS)
for(inti=0;
i<
(int)pIpNetTable->
dwNumEntries;
i++)//dwNumEntries为PMIB_IPNETTABLE结构体数组大小
inaddr.S_un.S_addr=pIpNetTable->
table[i].dwAddr;
//table[i]为PMIB_IPNETTABLE结构体数组本身
strcpy(ARPList[i].szIPAddrStr,inet_ntoa(inaddr));
formatMACToStr(ARPList[i].szHWAddrStr,pIpNetTable->
table[i].bPhysAddr);
ARPList[i].dwType=pIpNetTable->
table[i].dwType;
//Type
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的值来转换成字符显示
case3:
list.SetItemText(i,2,"
Dynamic"
);
break;
case4:
Static"
case1:
Invalid"
default:
Other"
}
deletepIpNetTable;
formatMACToStr(LPSTRlpHWAddrStr,constunsignedchar*HWAddr)//将用户输入的MAC地址字符转成相应格式
inti;
shorttemp;
charszStr[3];
strcpy(lpHWAddrStr,"
"
for(i=0;
6;
++i)
temp=(short)(*(HWAddr+i));
_itoa(temp,szStr,16);
if(strlen(szStr)==1)strcat(lpHWAddrStr,"
0"
strcat(lpHWAddrStr,szStr);
if(i<
5)strcat(lpHWAddrStr,"
-"
//加上-
formatStrToMAC(constLPSTRlpHWAddrStr,unsignedchar*HWAddr)//将用户输入的MAC地址字符转成数据包结构体需要的格式
unsignedinti,index=0,value,temp;
unsignedcharc;
_strlwr(lpHWAddrStr);
//转换成小写
for(i=0;
i<
strlen(lpHWAddrStr);
i++)
c=*(lpHWAddrStr+i);
if((c>
='
0'
&
&
c<
9'
)||(c>
a'
f'
))
if(c>
)temp=c-'
;
//数字
+0xa;
//字母,0xa表示字母的开始
if((index%2)==1)
value=value*0x10+temp;
HWAddr[index/2]=value;
elsevalue=temp;
index++;
if(index==12)break;
char*CSysInfo:
GetCurAdapterMAC(constshortnAdapterIndex)//获取网卡MAC
staticcharchTemp[12];
intj=0;
for(inti=0;
i<
18;
i++)//去掉mac地址中间的横线
if(AdapterList[nAdapterIndex].szHWAddrStr[i]!
-'
chTemp[j]=AdapterList[nAdapterIndex].szHWAddrStr[i];
j++;
returnchTemp;
五、负责部分(ARP数据包的发送和应答)
1)ARP数据包的发送和应答运行过程
a)ARPtest运行界面:
b)ARP发送数据包:
c)ARP获取目的MAC地址:
d)基于ARP欺骗的监听:
2)发送ARP包的编程实现:
填充数据包:
需要三个结构体,如下:
//DLCHeader
typedefstructDLCHeader
unsignedchar
DesMAC[6];
/*destinationHWaddrress*/
SrcMAC[6];
/*sourceHWaddresss*/
unsignedshort
Ethertype;
/*ethernettype*/
}DLCHEADER,*PDLCHEADER;
ARPFrame:
//ARPFrame
typedefstructARPFrame
HW_Type;
/*hardwareaddress*/
Prot_Type;
/*protocoladdress*/
HW_Addr_Len;
/*lengthofhardwareaddress*/
Prot_Addr_Len;
/*lengthofprotocoladdress*/
Opcode;
/*ARP/RARP*/
unsignedchar
Send_HW_Addr[6];
/*senderhardwareaddress*/
unsignedlong
Send_Prot_Addr;
/*senderprotocoladdress*/
Targ_HW_Addr[6];
/*targethardwareaddress*/
Targ_Prot_Addr;
/*targetprotocoladdress*/
padding[18];
}ARPFRAME,*PARPFRAME;
//ARPPacket=DLCheader+ARPFrame
typedefstructARPPacket
DLCHEADER
dlcHeader;
ARPFRAME
arpFrame;
}ARPPACKET,*PARPPACKET;
ARP发送用到的函数:
voidformatARPPacket(char*srcDLC,char*desDLC,char*srcMAC,char*srcIP,char*desMAC,char*desIP,intarpType);
voidSendARPPacket(shortnAdpaterIndex);
formatARPPacket
•voidCSender:
formatARPPacket(char*srcDLC,char*desDLC,char*srcMAC,char*srcIPchar*desMAC,char*desIP,intarpType)
•{
•memset(&
ARPPacket,0,sizeof(ARPPACKET));
//数据包初始化为0
•
•//DLC帧头
•CSysInfo:
formatStrToMAC(srcDLC,ARPPacket.dlcHeader.SrcMAC);
formatStrToMAC(desDLC,ARPPacket.dlcHeader.DesMAC);
•//源地址
CSysInfo:
formatStrToMAC(srcMAC,ARPPacket.arpFrame.Send_HW_Addr);
•ARPPacket.arpFrame.Send_Prot_Addr=inet_addr(srcIP);
•//目的地址
formatStrToMAC(desMAC,ARPPacket.arpFrame.Targ_HW_Addr);
•ARPPacket.arpFrame.Targ_Prot_Addr=inet_addr(desIP);
•/