ARP源碼實現及代碼說明,可直接編譯使用
ARP源碼
IP地址
typedef structIP_Address //32位的IP地址
{
u_char byte1;
u_char byte2;
u_char byte3;
u_char byte4;
}ip_address;
MAC地址結構
typedef structHard_Mac //48位的MAC地址
{
u_char byte1;
u_char byte2;
u_char byte3;
u_char byte4;
u_char byte5;
u_char
}Hard_Mac;
以太網頭
typedef structEthernet_Header //112位 48位SMac+48位SMac+16位協議類型以太網頭
{
Hard_Mac DMac; //(1)48位目MAC地址
Hard_Mac SMac; //(2)48位源MAC地址
WORD PType; //(3)16位協議類型
}Ethernet_Header;
ARP首部
typedef structARP_Header //定義ARP首部
{
Ethernet_Header FrameHeader;//幀頭
WORD
WORD PType3; //(5)16位協議類型
u_char HLeng; //(6)8位硬件地址長度
u_char PLeng; //(7)16位協議地址長度
WORD Oper; //(8)16位操作選項
Hard_Mac SMac3; //(9)48位源MAC地址
ip_address Saddr; //(10)32位源IP地址
Hard_Mac DMac3; //(11)48位目標MAC地址
ip_address Daddr; //(12)32位目標IP地址
BYTE
}ARP_Header;
以太網的數據部分大小必須是在46-1500之間,而ARP包只有28個字節,所以需要填充18個字節才能滿足要求。
全部源碼內容
#include "pcap.h"
#pragma comment(lib,"wpcap")
#pragma comment(lib,"ws2_32")
//=========數據包結構申明========================
typedef structIP_Address //32位的IP地址
{
u_char byte1;
u_char byte2;
u_char byte3;
u_char byte4;
}ip_address;
typedef structHard_Mac //48位的MAC地址
{
u_char byte1;
u_char byte2;
u_char byte3;
u_char byte4;
u_char byte5;
u_char byte6;
}Hard_Mac;
/* Ethernet header */
typedef structEthernet_Header //112位 48位SMac+48位SMac+16位協議類型以太網頭
{
Hard_Mac DMac; //(1)48位目MAC地址
Hard_Mac SMac; //(2)48位源MAC地址
WORD PType; //(3)16位協議類型
}Ethernet_Header;
typedef structARP_Header //定義ARP首部
{
Ethernet_Header FrameHeader;//幀頭
WORD HardWare; //(4)16位網卡硬件類型
WORD PType3; //(5)16位協議類型
u_char HLeng; //(6)8位硬件地址長度
u_char PLeng; //(7)16位協議地址長度
WORD Oper; //(8)16位操作選項
Hard_Mac SMac3; //(9)48位源MAC地址
ip_address Saddr; //(10)32位源IP地址
Hard_Mac DMac3; //(11)48位目標MAC地址
ip_address Daddr; //(12)32位目標IP地址
BYTE padding[18]; //填充0
}ARP_Header;
//=====================================================================
//填充APR數據包
//======================================================================
ARP_Header filtpacket()
{
inti;
ARP_Header ARPH; //發送的ARP包結構
//先初始化三層ARP的MAC地址
ARPH.DMac3.byte1= 0; ARPH.DMac3.byte2 = 0; ARPH.DMac3.byte3 = 0;
ARPH.DMac3.byte4= 0; ARPH.DMac3.byte5 = 0; ARPH.DMac3.byte6 = 0; //目標MAC地址
ARPH.SMac3.byte1= 0x00; ARPH.SMac3.byte2 = 0xE0; ARPH.SMac3.byte3 = 0x11;
ARPH.SMac3.byte4= 0x01; ARPH.SMac3.byte5 = 0xD0; ARPH.SMac3.byte6 = 0x05; //源MAC地址
//ARPH.FrameHeader.SMac.byte1= ARPH.SMac3.byte1; ARPH.FrameHeader.SMac.byte2 = ARPH.SMac3.byte2;ARPH.FrameHeader.SMac.byte3 = ARPH.SMac3.byte3;
//ARPH.FrameHeader.SMac.byte4= ARPH.SMac3.byte4; ARPH.FrameHeader.SMac.byte5 = ARPH.SMac3.byte5;ARPH.FrameHeader.SMac.byte6 = ARPH.SMac3.byte6; //源MAC地址
ARPH.FrameHeader.SMac.byte1= 0x00; ARPH.FrameHeader.SMac.byte2 =0xE0; ARPH.FrameHeader.SMac.byte3=0x11;
ARPH.FrameHeader.SMac.byte4= 0x01; ARPH.FrameHeader.SMac.byte5 = 0xD0; ARPH.FrameHeader.SMac.byte6=0x05; //源MAC地址
ARPH.FrameHeader.DMac.byte1= 0xFF; ARPH.FrameHeader.DMac.byte2 = 0xFF; ARPH.FrameHeader.DMac.byte3 = 0xFF;
ARPH.FrameHeader.DMac.byte4= 0xFF; ARPH.FrameHeader.DMac.byte5 = 0xFF; ARPH.FrameHeader.DMac.byte6 = 0xFF;//目標MAC地址
ARPH.FrameHeader.PType= htons(0x0806);//協議類型為ARP
ARPH.HardWare=htons(0x0001);//10M Ethernet
ARPH.PType3=htons(0x0800);//協議類型為IP
ARPH.HLeng= 6 ; //硬件地址長度
ARPH.PLeng= 4 ; //IP地址長度
ARPH.Oper= htons(0x0001) ; //請求操作
ARPH.Daddr.byte1=172;ARPH.Daddr.byte2=18;ARPH.Daddr.byte3=19;ARPH.Daddr.byte4=110;//目標IP地址
ARPH.Saddr.byte1=172;ARPH.Saddr.byte2=18;ARPH.Saddr.byte3=19;ARPH.Saddr.byte4=103;//源IP地址
for(i=0;i<18;i++)
{
ARPH.padding[i]=0;
}
returnARPH;
};
//==========================================================
//發送數據包
//==========================================================
void SendPacket(pcap_t*adhandle,ARP_Header ARPH)
{
//constu_char *Buff;
//Buff= &ARPH.FrameHeader.DMac.byte1 ; //結構首地址傳入Buff
if(pcap_sendpacket(adhandle,//Adapter
(u_char *)&ARPH, //buffer with the packet
sizeof(ARPH)//size
)!=0)
{
printf("發送數據包失敗\n");
}
//else
//printf("發送數據包成功!\n");
}
//=======================================================
//解析數據包
//=======================================================
void packet_handler(u_char *param, conststructpcap_pkthdr *header, constu_char *pkt_data)
{
//structtm *ltime;
//chartimestr[16];
/*convert the timestamp to readable format */
//ltime=localtime(&header->ts.tv_sec);
//strftime(timestr, sizeof timestr, "%H:%M:%S", ltime);
/*print timestamp and length of the packet */
//printf("%s.%.6dlen:%d \n", timestr, header->ts.tv_usec, header->len);
ARP_Header *ah;
Hard_Mac SMAC,DMAC;
Ethernet_Header *eh;
ah = (ARP_Header *) (pkt_data);
if(ah->FrameHeader.PType==1544&&
ah->Oper==512&&
ah->Daddr.byte1==172&&
ah->Daddr.byte2==18&&
ah->Daddr.byte3==19&&
ah->Daddr.byte4==116
&&ah->Saddr.byte1==172&&
ah->Saddr.byte2==18&&
ah->Saddr.byte3==19&&
ah->Saddr.byte4==103
)
{
/*輸出源IP地址,目的IP地址*/
printf("\n%d.%d.%d.%d-> %d.%d.%d.%d\n",
ah->Saddr.byte1,
ah->Saddr.byte2,
ah->Saddr.byte3,
ah->Saddr.byte4,
ah->Daddr.byte1,
ah->Daddr.byte2,
ah->Daddr.byte3,
ah->Daddr.byte4);
/*輸出目的地址,輸出源地址,輸入協議類型*/
eh=(Ethernet_Header*)pkt_data;
SMAC=eh->SMac;
printf("源地址 %.2x--%.2x--%.2x--%.2x--%.2x--%.2x\n"
,SMAC.byte1,SMAC.byte2,SMAC.byte3,SMAC.byte4,SMAC.byte5,SMAC.byte6);
//printf("源地址%.2x--%.2x--%.2x--%.2x--%.2x--%.2x\n"
// ,ah->FrameHeader.SMac.byte1,ah->FrameHeader.SMac.byte2,ah->FrameHeader.SMac.byte3,ah->FrameHeader.SMac.byte4,ah->FrameHeader.SMac.byte5,ah->FrameHeader.SMac.byte6);
DMAC=eh->DMac;
printf("目的地址 %.2x--%.2x--%.2x--%.2x--%.2x--%.2x\n"
,DMAC.byte1,DMAC.byte2,DMAC.byte3,DMAC.byte4,DMAC.byte5,DMAC.byte6);
printf("幀協議 %.4x\n",ntohs(eh->PType));
printf("硬件類型%.4x\n",ntohs(ah->HardWare));
printf("協議類型%.4x\n",ntohs(ah->PType3));
printf("操作類型%.4x\n",ntohs(ah->Oper));
printf("數據內容%x\n",ah->padding);
printf("\n\n==============================================================\n");
}
}
int main()
{
//打開網卡
pcap_if_t *alldevs;
pcap_if_t *d;
intinum;
inti=0;
pcap_t *adhandle;
charerrbuf[PCAP_ERRBUF_SIZE];
charpacket_filter[] ="arp";
/*Retrieve the device list */
if(pcap_findalldevs(&alldevs, errbuf) == -1)
{
fprintf(stderr,"Error in pcap_findalldevs:%s\n", errbuf);
exit(1);
}
/*Print the list */
for(d=alldevs;d; d=d->next)
{
printf("%d. %s", ++i, d->name);
if(d->description)
printf(" (%s)\n", d->description);
else
printf(" (No description available)\n");
}
if(i==0)
{
printf("\nNo interfaces found! Make sure WinPcap is installed.\n");
return-1;
}
printf("Enter the interface number (1-%d):",i);
scanf("%d", &inum);
if(inum< 1 || inum > i)
{
printf("\nInterface number out of range.\n");
/*Free the device list */
pcap_freealldevs(alldevs);
return-1;
}
/*Jump to the selected adapter */
for(d=alldevs,i=0; i< inum-1 ;d=d->next, i++);
/*Open the adapter */
if( (adhandle= pcap_open_live(d->name, // nameof the device
65536, // portion of the packet tocapture.
//65536 grants that the whole packet will be captured on all the MACs.
1, //promiscuous mode
1000, // read timeout
errbuf // error buffer
) ) ==NULL)
{
fprintf(stderr,"\nUnable to open the adapter.%s is not supported by WinPcap\n");
/*Free the device list */
pcap_freealldevs(alldevs);
return-1;
}
/*Check the link layer. We support only Ethernet for simplicity. */
/* if(pcap_datalink(adhandle) != DLT_EN10MB)
{
fprintf(stderr,"\nThisprogram works only on Ethernet networks.\n");
Free thedevice list
pcap_freealldevs(alldevs);
return -1;
}
printf("\nlisteningon %s...\n", d->description);
/* At thispoint, we don‘t need any more the device list. Free it */
pcap_freealldevs(alldevs);
/*start the capture */
//
while(9)
{
SendPacket(adhandle,filtpacket());
Sleep(20);
}
//pcap_loop(adhandle,0, packet_handler, NULL);
return0;
}
使用Wireshark抓取arp包
使用wireshark抓包如下圖2:
出現一大堆arp包。
雙擊其中過一個ARP內容如下圖3:
代碼中填充的
ARP目的MAC地址為00:00:00:00:00:00
ARP源MAC地址為:00:e0:11:01:d0:05
以太網目的地址:00:e0:11:01:d0:05
以太網源地址:FF:FF:FF:FF:FF:FF
協議類型為:0x0806(ARP)
硬件類型為:0x0001
協議地址長度:4(IP地址長度)
請求操作:0x0001
硬件地址長度:6
ARP目的IP地址:172.18.19.110
ARP源IP地址:172.18.19.103
再分享一下我老師大神的人工智能教程吧。零基礎!通俗易懂!風趣幽默!還帶黃段子!希望你也加入到我們人工智能的隊伍中來!http://www.captainbed.net
ARP源碼實現及代碼說明,可直接編譯使用