ARP協(xié)議實(shí)現(xiàn)和 ARP 測試
一、?? 實(shí)驗(yàn)環(huán)境:
Vmware下面安裝 Linux系統(tǒng),
VMware? Workstation 17 Pro
Unbuntu 20.4 ?
Winscp5.21 ,
SecureCRT 8.5
二、?? 編程語言
C語言, gcc 9.4.0
三、?? 功能框架
1、基礎(chǔ)通用功能定義
定義結(jié)構(gòu)體,
定義基本輸出函數(shù),
定義轉(zhuǎn)換函數(shù) ,
定義ip和mac射影隊(duì)列處理函數(shù)
2、向指定ip發(fā)送arp數(shù)據(jù)包
構(gòu)造arp數(shù)據(jù)包,向指定ip發(fā)送arp數(shù)據(jù)包
3、功偵聽和接收ARP包,顯示接收到的包內(nèi)容
4、持續(xù)接收功偵聽和接收ARP包, 顯示接收到的IP和mac?
5、列出局域網(wǎng)內(nèi)活動主機(jī)的ip和mac,保存到指定的文本文件中
6、偵聽和接收ARP包,查找ip-mac映射表,并回應(yīng)arp包
五、?? 已經(jīng)完成功能和實(shí)驗(yàn)關(guān)鍵過程
l? 1、基礎(chǔ)通用功能定義 ?
1.1、? 結(jié)構(gòu)定義,通用函數(shù)定義
gcc -c arp.c? -o? arp.o
1.2、把ip和 mac? 映射 ,添加到一個序列中
gcc -c dataio.c? -o? dataio.o
l? 2、向指定ip發(fā)送arp數(shù)據(jù)包 ,
2.1、編譯和鏈接
#gcc -c arp_send.c? -o? arp_send.o
#gcc -o arp_send?? arp_send.o? arp.o
2.2、運(yùn)行
#sudo? ./ arp_send? ?ens33
ens33是網(wǎng)卡名稱,作為程序參數(shù)
需要輸入目標(biāo)ip地址 , 比如 192.168.37.111,并回車確認(rèn)

?3、功偵聽和接收ARP包,顯示接收到的包內(nèi)容
每次運(yùn)行后,只能接受一次。
3.1、編譯和鏈接
#gcc -c arp_recieve.c? -o? arp_recieve.o
#gcc -o arp_recieve??? arp_recieve.o? arp.o
3.2、運(yùn)行
#sudo? ./arp_recieve ??

l? 4、持續(xù)接收回應(yīng)包, 生成局域網(wǎng)內(nèi)活動主機(jī)的ip和mac映射表,保存到指定的文本文件 ip_mac.txt
運(yùn)行后可以持續(xù)的接受arp回應(yīng)包 。
4.1、編譯和鏈接
#gcc -c arp_listener.c? -o? arp_listener.o
#gcc -o arp_listener??? arp_listener.o? arp.o? dataio.o
4.2、運(yùn)行
#sudo? ./arp_listener ??ens33
ens33是網(wǎng)卡名稱,作為程序參數(shù)
注意:如果出現(xiàn)段錯誤,請重新運(yùn)行程序
?
下面的圖片,左邊是持續(xù)接收界面,右邊是發(fā)送界面

5、有效ip和mac映射列表,
?5.1、通過gedit,emaic等編輯器,打開文本文件 ip_mac.txt

5.2、通過cat命令顯示 ?ip_mac.txt 內(nèi)容
?

6、在另外一個 linux 克隆機(jī)下面操作,
recv_echo 需要單獨(dú)在另外一個 linux下面運(yùn)行 。
修改靜態(tài)ip ,在第一個linux主機(jī)一個網(wǎng)段,重啟生效,
到arp 源碼目錄下面 ?
編譯 ?運(yùn)行 ?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
?
注意: 函數(shù) 在ip-mac映射表中查找mac
char* findMac(char* fileName, char* ip)??
?

六、?? 遇到的問題以及解決方法
1、?? 結(jié)構(gòu)體定義錯誤,? 通過在網(wǎng)上搜索資料解決。
結(jié)構(gòu)ether_header定義了以太網(wǎng)幀首部;結(jié)構(gòu)arphdr定義了其后的5個字段,其信息
用于在任何類型的介質(zhì)上傳送ARP請求和回答;ether_arp結(jié)構(gòu)除了包含arphdr結(jié)構(gòu)外,
還包含源主機(jī)和目的主機(jī)的地址。
定義常量
?
#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 */
?
以太網(wǎng)首部
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;
?
以太網(wǎng)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字節(jié)
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應(yīng)答表示為ARPOP_REPLY。
?//msg存放arp請求報文
? ? unsigned char msg[]={
? ? ? ? /*mac報文頭部 14B*/
? ? ? ? 0xff,0xff,0xff,0xff,0xff,0xff,/*目的mac地址*/
? ? ? ? 0x00,0x00,0x00,0x00,0xf9,0x7f/*源mac地址 根據(jù)自己修改 ubuntu_mac*/
? ? ? ? 0x08,0x06,/*幀類型*/
? ? ? ?
? ? ? ? /*ARP報文頭部 28B*/
? ? ? ? 0x00,0x01,/*硬件類型*/
? ? ? ? 0x08,0x00,/*協(xié)議類型*/
? ? ? ? 6,/*硬件地址長度*/
? ? ? ? 4,/*協(xié)議地址長度*/
? ? ? ? 0x00,0x01,/*1 ARP請求*/
? ? ? ? 0x00,0x0c,0x29,0x79,0xf9,0x7f,/*源mac地址 根據(jù)自己修改 ubuntu_mac*/
? ? ? ? 192,168,0,3,/*源IP 根據(jù)自己修改 ubuntu_ip*/
? ? ? ? 0x00,0x00,0x00,0x00,0x00,0x00,/*目的mac地址*/
? ? ? ? 192,168,0,0/*目的IP*/
? ? };
2、使用協(xié)議錯誤,通過在網(wǎng)上搜索資料解決。
PF_INET:IPv4互聯(lián)網(wǎng)協(xié)議族
PF_INET6:IPv6互聯(lián)網(wǎng)協(xié)議族
PF_LOCAL:本地通信的UNIX協(xié)議族
PF_PACKET:底層套接字的協(xié)議族
3、編譯報錯 : ?undefined reference to `main,
調(diào)用依賴沒有解決, 把依賴的文件也編譯進(jìn)去
gcc? -o arp_listener? arp_listener.o? arp.o?? dataio.o
3、 運(yùn)行 ./arp_listener
運(yùn)行軟件后出錯提示: socket error: Operation not permitted,
使用sudo提權(quán)
Sudo? ./arp_listener
?
4、使用網(wǎng)卡名稱默認(rèn)的eth0錯誤
?使用ifconfig 命令,查看當(dāng)前網(wǎng)卡名稱
5、虛擬機(jī)下的linux和windows pc? 不在一個局域網(wǎng)內(nèi),不能得到目標(biāo)主機(jī)的回應(yīng).
解決方法: 需要二者都使用靜態(tài)ip,在一個網(wǎng)段內(nèi) ,
Vmware 需要設(shè)置為bridge模式 。
==========QQ 75039960======================