ARP协议实现和 ARP 测试
一、 实验环境:
Vmware下面安装 Linux系统,
VMware® Workstation 17 Pro
Unbuntu 20.4
Winscp5.21 ,
SecureCRT 8.5
二、 编程语言
C语言, gcc 9.4.0
三、 功能框架
1、基础通用功能定义
定义结构体,
定义基本输出函数,
定义转换函数 ,
定义ip和mac射影队列处理函数
2、向指定ip发送arp数据包
构造arp数据包,向指定ip发送arp数据包
3、功侦听和接收ARP包,显示接收到的包内容
4、持续接收功侦听和接收ARP包, 显示接收到的IP和mac
5、列出局域网内活动主机的ip和mac,保存到指定的文本文件中
6、侦听和接收ARP包,查找ip-mac映射表,并回应arp包
五、 已经完成功能和实验关键过程
l 1、基础通用功能定义
1.1、 结构定义,通用函数定义
gcc -c arp.c -o arp.o
1.2、把ip和 mac 映射 ,添加到一个序列中
gcc -c dataio.c -o dataio.o
l 2、向指定ip发送arp数据包 ,
2.1、编译和链接
#gcc -c arp_send.c -o arp_send.o
#gcc -o arp_send arp_send.o arp.o
2.2、运行
#sudo ./ arp_send ens33
ens33是网卡名称,作为程序参数
需要输入目标ip地址 , 比如 192.168.37.111,并回车确认

3、功侦听和接收ARP包,显示接收到的包内容
每次运行后,只能接受一次。
3.1、编译和链接
#gcc -c arp_recieve.c -o arp_recieve.o
#gcc -o arp_recieve arp_recieve.o arp.o
3.2、运行
#sudo ./arp_recieve

l 4、持续接收回应包, 生成局域网内活动主机的ip和mac映射表,保存到指定的文本文件 ip_mac.txt
运行后可以持续的接受arp回应包 。
4.1、编译和链接
#gcc -c arp_listener.c -o arp_listener.o
#gcc -o arp_listener arp_listener.o arp.o dataio.o
4.2、运行
#sudo ./arp_listener ens33
ens33是网卡名称,作为程序参数
注意:如果出现段错误,请重新运行程序
下面的图片,左边是持续接收界面,右边是发送界面

5、有效ip和mac映射列表,
5.1、通过gedit,emaic等编辑器,打开文本文件 ip_mac.txt

5.2、通过cat命令显示 ip_mac.txt 内容

6、在另外一个 linux 克隆机下面操作,
recv_echo 需要单独在另外一个 linux下面运行 。
修改静态ip ,在第一个linux主机一个网段,重启生效,
到arp 源码目录下面
编译 运行 recv_echo
gcc -c arp.c -o arp.o
gcc -c recv_echo.c -o recv_echo.o
gcc -o recv_echo recv_echo.o arp.o
sudo ./ recv_echo ens33
注意: 函数 在ip-mac映射表中查找mac
char* findMac(char* fileName, char* ip)

六、 遇到的问题以及解决方法
1、 结构体定义错误, 通过在网上搜索资料解决。
结构ether_header定义了以太网帧首部;结构arphdr定义了其后的5个字段,其信息
用于在任何类型的介质上传送ARP请求和回答;ether_arp结构除了包含arphdr结构外,
还包含源主机和目的主机的地址。
定义常量
#define EPT_IP 0x0800 /* type: IP */
#define EPT_ARP 0x0806 /* type: ARP */
#define EPT_RARP 0x8035 /* type: RARP */
#define ARP_HARDWARE 0x0001 /* Dummy type for 802.3 frames */
#define ARP_REQUEST 0x0001 /* ARP request */
#define ARP_REPLY 0x0002 /* ARP reply */
以太网首部
typedef struct ehhdr
{
unsigned char eh_dst[6]; /* destination ethernet addrress */
unsigned char eh_src[6]; /* source ethernet addresss */
unsigned short eh_type; /* ethernet pachet type */
}EHHDR, *PEHHDR;
以太网arp字段
typedef struct arphdr
{
//arp首部
unsigned short arp_hrd; /* format of hardware address */
unsigned short arp_pro; /* format of protocol address */
unsigned char arp_hln; /* length of hardware address */
unsigned char arp_pln; /* length of protocol address */
unsigned short arp_op; /* ARP/RARP operation */
unsigned char arp_sha[6]; /* sender hardware address */
unsigned long arp_spa; /* sender protocol address */
unsigned char arp_tha[6]; /* target hardware address */
unsigned long arp_tpa; /* target protocol address */
}ARPHDR, *PARPHDR;
整个arp报文包,总长度42字节
typedef struct arpPacket
{
EHHDR ehhdr;
ARPHDR arphdr;
} ARPPACKET, *PARPPACKET;
#define ETH_HDRLEN 14
#define IP4_HDRLEN 20
#define ARP_HDRLEN 28
#define ARPOP_REQUEST 1
#define ARPOP_REPLY 2
ARP请求表示为ARPOP_REQUEST,ARP应答表示为ARPOP_REPLY。
//msg存放arp请求报文
unsigned char msg[]={
/*mac报文头部 14B*/
0xff,0xff,0xff,0xff,0xff,0xff,/*目的mac地址*/
0x00,0x00,0x00,0x00,0xf9,0x7f/*源mac地址 根据自己修改 ubuntu_mac*/
0x08,0x06,/*帧类型*/
/*ARP报文头部 28B*/
0x00,0x01,/*硬件类型*/
0x08,0x00,/*协议类型*/
6,/*硬件地址长度*/
4,/*协议地址长度*/
0x00,0x01,/*1 ARP请求*/
0x00,0x0c,0x29,0x79,0xf9,0x7f,/*源mac地址 根据自己修改 ubuntu_mac*/
192,168,0,3,/*源IP 根据自己修改 ubuntu_ip*/
0x00,0x00,0x00,0x00,0x00,0x00,/*目的mac地址*/
192,168,0,0/*目的IP*/
};
2、使用协议错误,通过在网上搜索资料解决。
PF_INET:IPv4互联网协议族
PF_INET6:IPv6互联网协议族
PF_LOCAL:本地通信的UNIX协议族
PF_PACKET:底层套接字的协议族
3、编译报错 : undefined reference to `main,
调用依赖没有解决, 把依赖的文件也编译进去
gcc -o arp_listener arp_listener.o arp.o dataio.o
3、 运行 ./arp_listener
运行软件后出错提示: socket error: Operation not permitted,
使用sudo提权
Sudo ./arp_listener
4、使用网卡名称默认的eth0错误
使用ifconfig 命令,查看当前网卡名称
5、虚拟机下的linux和windows pc 不在一个局域网内,不能得到目标主机的回应.
解决方法: 需要二者都使用静态ip,在一个网段内 ,
Vmware 需要设置为bridge模式 。
==========QQ 75039960======================