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

 

### 回答1: C Builder 是一个 Borland 公司开发的集成开发环境(IDE),主要用于 Windows 平台上的软件开发。ARP(Address Resolution Protocol)是一个网络协议,用于将 IP 地址解析成 MAC 地址。下面是对 C Builder 中 ARP 源码的简要说明。 C Builder 提供了一个名为 IPHLPAPI 的库,其中包含了许多网络相关的函数和数据结构,包括 ARP 相关的函数。在 C Builder 中使用 ARP 功能,需要引入头文件"iphlpapi.h",并连接 IPHLPAPI 库。 ARP 相关的函数包括 GetIpNetTable 和 SendARP 等。GetIpNetTable 函数用于获取本地计算机的 ARP 表,该表存储了 IP 地址和相应的 MAC 地址。SendARP 函数用于向局域网中的其他设备发送 ARP 请求,以获取指定 IP 地址的 MAC 地址。 使用 GetIpNetTable 函数,可以获得当前系统中的 ARP 表信息。该函数需要传入一个 MIB_IPNETTABLE 结构体指针,用于接收返回的 ARP 表数据。MIB_IPNETTABLE 结构体包含了 ARP 表的相关信息,如 IP 地址、MAC 地址、接口索引等。 使用 SendARP 函数,可以向指定的 IP 地址发送 ARP 请求。该函数需要传入目标 IP 地址和目标 MAC 地址的缓冲区,以及用于发送请求的接口的 IP 地址。发送 ARP 请求后,目标设备会回应一个 ARP 应答,其中包含了目标 MAC 地址。 在 C Builder 中,可以根据需要调用这些 API 函数,实现 ARP 表的获取和 ARP 请求的发送。通过 ARP 功能,可以方便地实现 IP 地址和 MAC 地址的映射,从而实现网络通信中的数据包传输等功能。同时,利用 ARP 也可以进行网络扫描和地址欺骗等操作。 ### 回答2: C Builder(也称为C++ Builder)是一个集成开发环境(IDE),主要用于开发和编译基于C和C++语言的应用程序。它是由Embarcadero Technologies开发和维护的。 ARP(地址解析协议)是一个用于在IPv4网络中解析IP地址与物理MAC地址之间映射关系的协议。它通过发送ARP请求广播包来查询所需IP地址对应的MAC地址,然后将结果保存在本地的ARP缓存中,以便后续通信时进行快速映射。 关于C Builder ARP源码,这个问题可能需要具体指明是指哪方面的源码,因为C Builder是一套完整的开发工具,其支持的范围非常广泛,包括图形界面设计、数据库连接、网络通信等多个领域。而ARP则是一个网络协议,与网络通信和网络设备有关。 如果是指C Builder中用于实现ARP协议的源码,一般需要使用相关的网络编程库,例如Winsock或者Linux的socket编程接口。你可以使用C++编写一个程序,通过这些库函数实现ARP请求和响应的功能。具体实现的流程包括构建ARP请求/响应报文、设置报文的目标IP和目标MAC地址、发送/接收报文等。 具体来说,你可以调用一些函数来创建ARP报文的数据包,例如使用WinSock库的sendto函数来发送报文,然后使用recvfrom函数来接收响应报文。在接收到ARP响应后,你可以解析报文中的源MAC地址,并将其存储在一个ARP缓存表中,以供后续的网络通信使用。 总而言之,C Builder是一个功能强大的集成开发环境,用于开发C和C++应用程序。而ARP协议是一种网络协议,用于解析IP地址和MAC地址之间的映射关系。如果要编写C Builder中的ARP源码,你需要使用相关的网络编程库来发送和接收ARP报文,并且按照协议规定解析报文中的数据,进行MAC地址的映射和缓存。 ### 回答3: c builder arp 源码主要是指在C语言中使用builder模式来实现arp协议相关功能的代码Arp协议是用于将网络层IP地址映射到链路层MAC地址的协议。在C语言中,我们可以通过构建arp包的数据结构来实现arp协议。 首先,我们可以定义一个ArpBuilder的结构体,用于存储需要构建的arp包的各个字段。这个结构体可以包含源MAC地址、源IP地址、目的MAC地址、目的IP地址等字段。 接下来,我们可以定义一系列的函数,用于设置这些字段的值。例如,可以定义一个函数setSrcMac()用于设置源MAC地址,定义一个函数setSrcIp()用于设置源IP地址等。 然后,我们可以定义一个buildArpPacket()函数,用于根据ArpBuilder结构体中的字段的值构建一个arp包。在这个函数中,我们可以使用C语言中的struct来定义arp包的数据结构,并逐个将字段的值填入。 最后,我们可以定义一个sendArpPacket()函数,用于将构建好的arp包发送到网络中。在这个函数中,我们可以使用C语言中的socket编程来发送网络数据包。 总之,c builder arp 源码就是使用C语言中的builder模式来构建arp包,并通过socket编程发送到网络中的代码。这样,我们就可以在C语言中实现arp协议相关功能。
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值