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 byte6;

}Hard_Mac;

以太网头

typedef structEthernet_Header //112 48SMac+48SMac+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 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;

以太网的数据部分大小必须是在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 48SMac+48SMac+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包结构

    //先初始化三层ARPMAC地址

    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

猜你喜欢

转载自www.cnblogs.com/swncz/p/10445590.html