2)发送ARP包的编程实现:
填充数据包:
需要三个结构体,如下: // DLC Header
typedef struct DLCHeader
{
unsigned char DesMAC[6]; /* destination HW addrress */ unsigned char SrcMAC[6]; /* source HW addresss */ unsigned short Ethertype; /* ethernet type */ } DLCHEADER, *PDLCHEADER; ARP Frame: // ARP Frame
typedef struct ARPFrame {
unsigned short HW_Type; /* hardware address */ unsigned short Prot_Type; /* protocol address */
unsigned char HW_Addr_Len; /* length of hardware address */ unsigned char Prot_Addr_Len; /* length of protocol address */ unsigned short Opcode; /* ARP/RARP */
unsigned char Send_HW_Addr[6]; /* sender hardware address */
unsigned long Send_Prot_Addr; /* sender protocol address */ unsigned char Targ_HW_Addr[6]; /* target hardware address */ unsigned long Targ_Prot_Addr; /* target protocol address */ unsigned char padding[18]; } ARPFRAME, *PARPFRAME;
//ARP Packet = DLC header + ARP Frame typedef struct ARPPacket {
DLCHEADER dlcHeader; ARPFRAME arpFrame; } ARPPACKET, *PARPPACKET; ARP发送用到的函数:
void formatARPPacket(char* srcDLC,char* desDLC,char* srcMAC,char* srcIP,char* desMAC,char* desIP,int arpType);
void SendARPPacket(short nAdpaterIndex);
formatARPPacket
? void CSender::formatARPPacket(char* srcDLC,char*
srcMAC,char* srcIP char* desMAC,char* desIP,int arpType)
desDLC,char*
? {
? memset(&ARPPacket, 0, sizeof(ARPPACKET)); // 数据包初始化为0
? ? // DLC帧头
? CSysInfo::formatStrToMAC(srcDLC,ARPPacket.dlcHeader.SrcMAC); ? CSysInfo::formatStrToMAC(desDLC,ARPPacket.dlcHeader.DesMAC); ?
? // 源地址
CSysInfo::formatStrToMAC(srcMAC,ARPPacket.arpFrame.Send_HW_Addr);
? ARPPacket.arpFrame.Send_Prot_Addr = inet_addr(srcIP);
? // 目的地址
? CSysInfo::formatStrToMAC(desMAC,ARPPacket.arpFrame.Targ_HW_Addr);
? ARPPacket.arpFrame.Targ_Prot_Addr = inet_addr(desIP);
? // arp包类型
? ARPPacket.arpFrame.Opcode = htons((unsigned short)arpType); ? // 自动填充常量
? // DLC Header的以太网类型
? ARPPacket.dlcHeader.Ethertype = htons((unsigned short)0x0806); ? // 硬件类型
? ARPPacket.arpFrame.HW_Type = htons((unsigned short)1); ?
? // 上层协议类型
? ARPPacket.arpFrame.Prot_Type = htons((unsigned short)0x0800);
? // MAC地址长度
? ARPPacket.arpFrame.HW_Addr_Len = (unsigned char)6;
? // IP地址长度
? ARPPacket.arpFrame.Prot_Addr_Len = (unsigned char)4; ? }
SendARPPacket
? void CSender::SendARPPacket(short nAdapterIndex) ? {
? char *AdapterDeviceName = CSysInfo::GetCurAdapterName(nAdapterIndex);
// 获得网卡名字
? lpAdapter = PacketOpenAdapter(AdapterDeviceName); // 打开网卡
? if (!lpAdapter || (lpAdapter->hFile == INVALID_HANDLE_VALUE)) ? {
? ? ? }
AfxMessageBox(\打开网卡错误!\return;
? lpPacket = PacketAllocatePacket(); // 给PACKET结构指针分配内存 ? if (lpPacket == NULL) ? { ? ? ?
PacketCloseAdapter(lpAdapter);
AfxMessageBox(\错误!\return;
? }
? PacketInitPacket(lpPacket, &ARPPacket, sizeof(ARPPacket)); //初始化
PACKET结构指针
? if (PacketSetNumWrites(lpAdapter, 1) == 0) // 每次只发送一个包 ? { ? ? ? ? ? }
? if (PacketSendPacket(lpAdapter, lpPacket, true) == 0) // Send ? { ? PacketFreePacket(lpPacket); ? ? ? ? }
? /*PacketFreePacket(lpPacket); ? PacketCloseAdapter(lpAdapter);*/ ? }
PacketCloseAdapter(lpAdapter);
AfxMessageBox(\发送数据包错误!\return;
PacketFreePacket(lpPacket); PacketCloseAdapter(lpAdapter);
//AfxMessageBox(\错误!\return;
3)ARP数据包发送实现代码:
#include \#include \#include \
ARPPACKETCSender::ARPPacket; LPADAPTER CSender::lpAdapter;
LPPACKET CSender::lpPacket;
CSender::CSender(void) { }
CSender::~CSender(void) { }
void CSender::SendARPPacket(short nAdapterIndex) {
char *AdapterDeviceName = CSysInfo::GetCurAdapterName(nAdapterIndex); // 获得网卡名字
lpAdapter = PacketOpenAdapter(AdapterDeviceName); // 打开网卡 if (!lpAdapter || (lpAdapter->hFile == INVALID_HANDLE_VALUE)) { }
lpPacket = PacketAllocatePacket(); // 给PACKET结构指针分配内存 if (lpPacket == NULL) { }
PacketCloseAdapter(lpAdapter);
AfxMessageBox(\错误!\return;
AfxMessageBox(\打开网卡错误!\return;
PacketInitPacket(lpPacket, &ARPPacket, sizeof(ARPPacket)); //初始化PACKET
结构指针
if (PacketSetNumWrites(lpAdapter, 1) == 0) // 每次只发送一个包 { }
PacketFreePacket(lpPacket);
PacketCloseAdapter(lpAdapter);
AfxMessageBox(\错误!\return;
if (PacketSendPacket(lpAdapter, lpPacket, true) == 0) // Send {
}
}
PacketFreePacket(lpPacket); PacketCloseAdapter(lpAdapter);
AfxMessageBox(\发送数据包错误!\return;
PacketFreePacket(lpPacket); PacketCloseAdapter(lpAdapter);
void CSender::formatARPPacket(char* srcDLC,char* desDLC,char* srcMAC,char* srcIP, {
char* desMAC,char* desIP,int arpType)
memset(&ARPPacket, 0, sizeof(ARPPACKET)); // 数据
包初始化为0
CSysInfo::formatStrToMAC(srcDLC,ARPPacket.dlcHeader.SrcMAC); // DLC帧头 CSysInfo::formatStrToMAC(desDLC,ARPPacket.dlcHeader.DesMAC);
CSysInfo::formatStrToMAC(srcMAC,ARPPacket.arpFrame.Send_HW_Addr); // 源
地址 ARPPacket.arpFrame.Send_Prot_Addr = inet_addr(srcIP); CSysInfo::formatStrToMAC(desMAC,ARPPacket.arpFrame.Targ_HW_Addr); // 目的地址
ARPPacket.arpFrame.Targ_Prot_Addr = inet_addr(desIP);
ARPPacket.arpFrame.Opcode = htons((unsigned short)arpType); // arp包类型
// 自动填充常量
ARPPacket.dlcHeader.Ethertype = htons((unsigned short)0x0806); // DLC
Header的以太网类型 ARPPacket.arpFrame.HW_Type = htons((unsigned short)1); // 硬件类型 ARPPacket.arpFrame.Prot_Type = htons((unsigned short)0x0800); // 上层协议类型
ARPPacket.arpFrame.HW_Addr_Len = (unsigned char)6; // MAC地址长度
ARPPacket.arpFrame.Prot_Addr_Len = (unsigned char)4; // IP地址长度 }
六、课程设计小结
通过本次课程设计,进一步熟悉了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就实现了欺骗和监听。