[Linux]ARP協議

概念:

1. ARP協議(地址解析協議):由IP地址轉換為MAC地址的協議。IP地址:網絡號+主機號。MAC地址:數據鏈路層的物理地址(硬件地址)。IP協議使用了ARP協議,因此被劃歸為網絡層,但其用途是從網絡層使用的IP地址解析出數據鏈路層的硬件地址,因此有些也將其劃歸為數據鏈路層。與ARP協議成對的協議為RARP,它是從MAC地址到IP地址的轉換。

2. 網絡層使用的是IP地址,但在實際網絡的鏈路上傳送數據幀時,最終還是使用網絡的硬件地址。但IP地址和網絡的硬件地址本身存在格式上的不同,也沒有什么直接的映射關系。同時,網絡上也有不同的主機加入進來,或撤走一些主機,更換網絡適配器也會使硬件地址改變,因此引入了ARP協議,ARP協議主要解決此類問題的方法是在主機ARP高速緩存中存放一個從IP地址到硬件地址的映射表,并且這個映射表經常動態更新。

3. 每個主機都有一個ARP高速緩存,里面有局域網的主機和路由器的IP到硬件地址的映射表,這些都是該主機目前知道的一些地址。舉個栗子哦,當主機A要給主機B發送報文時,主機A會在高速緩存中找是否有B的IP地址,如果有,則在ARP高速緩存中找到對應的硬件地址,再把這個地址寫入MAC幀,然后通過局域網把該MAC幀發送到此硬件地址。也有可能查不到其IP地址,可能是由于主機B才入網,也可能是主機A剛加電,高速緩存還是空的。這種情況的話,主機A會自動運行ARP,來找出硬件地址。

(1) ARP在局域網中廣播請求分組,找主機B的IP地址
(2) 在局域網上運行的主機都可以接收到ARP廣播的消息,但只有主機B會有響應,其他主機則忽略該廣播。
(3)主機B響應分組后,會在ARP響應分組中寫入自己的硬件地址,此時的響應分組是單播的。剛剛廣播是因為不知道主機是哪一個,現在知道了具體是哪一個主機后,主機B直接給主機A響應,因此是普通的單播。
(4) 主機A收到主機B的響應分組后,在ARP高速緩存中寫入主機B的從IP地址到硬件地址的映射。為什么要將其寫入ARP高速緩存呢,你發送數據報可能不止一次,當你發送完之后,主機B也給主機A響應后,可能也會發送數據報,這時如果沒有ARP高速緩存,可能主機B也得以廣播的方式先找到主機A的IP,再找硬件地址,這樣就大大降低了網絡的通信量,因此使用ARP來增加網絡的通信量,也提供了方便。

4. ARP把保存在高速緩存中的每一個映射地址項目都設置生存時間,超過生存時間的項目就從高速緩存中刪除掉。比如說主機A給主機B發數據,某一天,主機B的網絡適配器壞了,B更換了一塊,這時其硬件地址也被修改,這樣的話高速緩存中存的還是原來的那個地址,這下你肯定找不到確定的硬件地址,有了生存時間后,你可以在限定的時間內找,如果找不到的話,就將原先的硬件地址刪除,再重新廣播發送ARP請求分組,重新找到B。繼續上述的步驟,在高速緩存中寫入正確的硬件地址即可。

5. ARP協議是解決局域網的情況,如果是不同的網絡中的主機間的傳送數據報呢?這里我們涉及到路由器的概念。主機A無法直接解析主機B的硬件地址,我們這時通過連接到主機A的路由器來進行轉發,找到另一網絡(通過將路由器A的IP轉化為硬件地址,以便將IP數據報寫入路由器A,A從轉發表中找到下一跳路由B,同時解析出路由器B的硬件地址,于是再將數據報轉發到路由B上),再通過路由器廣播的方式(解析目的主機的硬件地址),找到正確的主機,傳送數據報。

關于ARP,主要有四種典型情況:
1. 發送方是主機,把IP數據報發送到同一網絡的另一個主機,此時主機A發送ARP請求分組,廣播,找到目的主機的硬件地址
2. 發送方是主機,把IP數據報發送到不同網絡的另一個主機,這時主機A發送ARP請求分組,找到主機A的路由器的硬件地址,剩下的工作由路由器完成。
3. 發送方是路由器,把IP數據報轉發到同一網絡的另一個主機,此時路由器發送ARP請求分組,廣播,找到目的主機的硬件地址
4. 發送方是路由器,把IP數據報轉發到不同網絡的另一個主機,這時路由器R1發送ARP請求分組,找到下一跳路由器R2的硬件地址,剩下的工作由路由器R2完成。

下面我們來寫個腳本來實現抓取主機MAC地址:

#!/bin/bash
net='192.168.127.'   //是我自己的主機IP
i=1
count=0
while [ $i -le 254 ]
doif [ $count -eq 20 ];thencount=0sleep 1fiping -c1 $net$i &   //檢查網絡是否連通let i++let count++donewait

我們可以使用arp -a來查看緩存中的MAC地址。如下:

這里寫圖片描述
這里寫圖片描述

其中顯示incomplete的就是沒有存入緩存中的。我們可以過濾一下。

#!/bin/bash
net='192.168.127.'
i=1
count=0
while [ $i -le 254 ]
doif [ $count -eq 20 ];thencount=0sleep 1fiping -c1 $net$i &let i++let count++donewait
arp -a | grep -v 'incomplete'

這次就會直接將沒有連接的IP過濾掉,運行結果為:

這里寫圖片描述

這樣我們就很好的抓取到了對應主機的MAC地址。

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/news/382681.shtml
繁體地址,請注明出處:http://hk.pswp.cn/news/382681.shtml
英文地址,請注明出處:http://en.pswp.cn/news/382681.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

Makefile使用及多文件gdb 調試

文件內容 [koulocalhost makefile]$ cat 1.c #include "3.h" int main() {key_t key ftok(".",1);printf("%d\n",add(1,2));return 0; }[koulocalhost makefile]$ cat 2.c #include "3.h" int add(int a, int b) {return a b; } [k…

C++ 對引用的理解2

1.指針就是數據或代碼在內存中的地址,指針變量指向的就是內存中的數據或代碼。這里有一個關鍵詞需要強調,就是內存,指針只能指向內存,不能指向寄存器或者硬盤,因為寄存器和硬盤沒法尋址。 2.其實 C 代碼中的大部分內容…

Ubuntu各版本主要差異

Ubuntu各版本主要差異 (重定向自Ubuntu , kubuntu與xubuntu的差別 ) Ubuntu官方考慮到使用者的不同需求,提供各種不同的發行版。這幾種發行版本的差別在于桌面環境和預設安裝的軟體不同,但套件庫是采用一樣的,所以您當然可以在安…

[Linux]CRC校驗

CRC(Cyclic Redundancy Check),循環冗余校驗碼,是數據通信領域中最常用的一種差錯校驗碼,其特征是信息字段和校驗字段的長度可以任意選定。 CRC校驗步驟: CRC分為兩部分,前部分為信息碼,后部分為校驗碼;設…

visual studio 2015 配置好qt5后, 第一次運行出現 無法打開源文件“QtWidgets/QApplication”和無法運行rc.exe的解決方案

無法打開源文件“QtWidgets/QApplication” a.在工程中右擊項目,點擊屬性。 b.選擇VC目錄->包含目錄 c.選擇Qt安裝目錄中的頭文件包含目錄,一般為Qt版本號/版本號/編譯器名/include 比如:E:\Qt\Qt5.6.3\5.6.3\msvc2015\include 在C\C>附…

怎么在vs中查看一個數組的所有元素

在監視窗口,我們想要查看所有的數組元素。 這個時候 int arr[] {1,2,3} arr只顯示1 正確的方法 arr,10

[Linux]NAT和代理服務器

1. NAT:(Network Address Translation)是網絡地址轉換。 我們有這樣一種場景,在專用網內部的一些主機本來已經分配到了本地IP地址,但現在又想和因特網上的主機通信,我們可以設法再申請一些全球IP地址&…

使用 C++的第三方庫 jsoncpp的步驟以及出現的問題

Jsoncpp 是一個json解析庫 下載地址為: http://sourceforge.net/projects/jsoncpp/ 方法一:使用Jsoncpp生成的lib文件 解壓上面下載的Jsoncpp文件,在jsoncpp-src-0.5.0/makefiles/vs71目錄里找到jsoncpp.sln,用VS2008版本編譯&am…

常用的友元重載運算符OSTREAM

對<<運算符重載&#xff0c;讓他能和cout一起顯示對象內容。 顯示值可以使用show()&#xff0c;但是使用cout<<更方便。 ostream類對該運算符進行了重載&#xff0c;將其轉換成輸出工具。 cout就是一個ostream的對象&#xff0c;他可以自動識別所有的c基本類型。…

python字符串系列

1.find方法用于在長串中查找子串&#xff0c;返回子串中最左位置的下標&#xff0c;如果沒找到&#xff0c;則返回-1 2.join方法用于在隊列中添加元素 3.lower返回字符串的小寫字母版 4.replace返回字符串中所有匹配項均被替換之后得到字符串 5.split將字符串分割成序列 6.stri…

C++ wstring 與 string 之間的相互轉換.

方式一&#xff1a;調用Windows API #include <Windows.h> //將string轉換成wstring wstring string2wstring(string str) { wstring result; //獲取緩沖區大小&#xff0c;并申請空間&#xff0c;緩沖區大小按字符計算 int len MultiByteToWideChar(CP_ACP, 0,…

linux網絡編程Internet Socket地址,套接字,和函數

文章內容節選《linux/UNIX 系統網絡編程》 Internet domain socket地址有兩種&#xff1a;IPv4 IPv6 IPv4被存儲在結構體中&#xff0c; 該結構體在 netinet/in.h 中進行定義 cd usr/include/netinet/in.h struct in_addr {in_addr_t s_addr; //32位IPv4地址 }struct so…

淺談socket網絡編程函數參數(一)

socket函數解析 概念: 每個進程的進程空間里都有一個socket描述符表。套接字描述符表屬于一個進程&#xff0c;而socket地址結構位于操作系統的內核緩沖。 函數原型 #include <sys/socket.h>int socket(int domain, int type, int protocol);函數參數 family參數 默…

C++ const 與 extern

C語言中&#xff0c; const修飾的全局變量是外部鏈接屬性&#xff0c;比如在 a.c文件中有 const int m_a 10; 在b.c中想用這個全局變量&#xff0c; 在b.c中這樣 extern const int m_a; 就可以使用a.c中的m_a C 語言中&#xff0c; const修飾的全局變量是內部鏈接屬性&#x…

淺談socket網絡編程函數參數(二)

bind()函數 bind()函數把一個地址族中的特定地址賦給socket。 例如對應AF_INET、AF_INET6就是把一個ipv4或ipv6地址和端口號組合賦給socket。 int bind(int sockfd, const struct sockaddr *addr, socklen_t addrlen);參數解析 sockfd&#xff1a;即socket描述字&#xff0c…

對引用的理解3

對數組的引用&#xff0c; 相關語法 int main() { //引用于法// type &引用名 原名//數組的引用//1) 先定義一個數組int array[10];int (&refArray)[10] array;for (int i 0; i < 10; i) {array[i] i;}for (int i 0; i < 10; i) {cout << refArray[i…

運算符與,|與||的區別

|和&是位運算&#xff0c;運算結果是二進制數。 &&,||是邏輯運算&#xff0c;運算結果是真&#xff0c;或者假。 6&3110&0110102 6|3110|0111117&, &&和||計算時注意&#xff0c; 題目&#xff1a;條件1&&條件2&&條件3 如…

C++ 對引用的理解4

引用的注意事項 // 引用注意事項&#xff0c; 不能返回局部變量的引用 int & test3() { //因為局部變量出了函數體外 就會被銷毀int a 10;return a; }// 引用注意事項&#xff0c; 返回值如果是引用&#xff0c; 那么函數可以作為左值進行運算 int & test4() {static…

關于argc和argv的輸出

代碼 #include <stdio.h>int main(int argc ,char * argv[]) {printf("argc ->%d\n",argc);for(int i 0; i < argc;i){printf("%s\n",argv[i]);}return 0; } 輸出結果 [koulocalhost 8_6網絡計算器]$ ./a.out 192.168.1.1 9000 argc ->…

C++ 對引用的理解5

常量引用 int main() { // int &m 10; // 錯誤&#xff0c; 引用必須引一塊合法的內存空間&#xff08;什么是合法的內存空間&#xff0c; 這個10在程序中有內存嗎&#xff1f;&#xff09;const int &m 10; //加入const后&#xff0c;語法就通過了&#xff0c;編譯…