openwrt利用arp擷取區域網路裝置IP
文章目錄
- openwrt利用arp擷取區域網路裝置IP
- 1. 前言
- 2. ARP概念
- 3. arp區域網路搜尋裝置實作思路和代碼
1. 前言
目前我們通過arp協定搜尋區域網路裝置,根據區域網路裝置位址判斷子裝置是否線上(子裝置ip為靜态ip位址),是以這裡簡單總結一下arp的使用。
2. ARP概念
以下内容來自維基百科:
ARP:位址解析協定(英語:Address Resolution Protocol,縮寫:ARP)是一個通過解析網絡層位址來找尋資料鍊路層位址的網絡傳輸協定,它在IPv4中極其重要。ARP最初在1982年的RFC 826(征求意見稿)[1]中提出并納入網際網路标準STD 37。ARP也可能指是在多數作業系統中管理其相關位址的一個程序。
ARP是通過網絡位址來定位MAC位址。 ARP已經在很多網路層和資料連結層之間得以實作,包括IPv4,Chaosnet, DECnet和Xerox PARC Universal Packet(PUP)使用IEEE 802标準, 光纖分布式資料接口, X.25, 幀中繼和異步傳輸模式(ATM),IEEE 802.3和IEEE 802.11标準上IPv4占了多數流量。
在IPv6中鄰居發現協定(NDP)用于代替位址解析協定(ARP)。
3. arp區域網路搜尋裝置實作思路和代碼
上面我們已經說過主要是通過配置子裝置為靜态ip,沒有靜态ip的話知曉裝置mac位址也可以(這也是裝置不要輕易洩露mac位址的原因,容易被嗅探)。然後通過arp資訊對照ip或mac來确認裝置是否線上,這裡有個問題時arp的資訊存在2分鐘左右的緩存,是以為了防止查找出的資訊為緩存資訊,我們可以清除緩存之後等待一段時間再擷取arp資訊,代碼如下(不同系統和裝置可能有差異,這裡以openwrt為主):
package main
import (
"bufio"
"os/exec"
"strings"
"time"
"github.com/wonderivan/logger"
)
func main() {
//這裡的裝置名稱可通過ifconfig查找
GetLANDevIP("eth0")
}
func GetLANDevIP(devName string) ([]string, error) {
//清除對應裝置的arp緩存
cmd := exec.Command("ip", "neigh", "flush", "dev", devName)
output, err := cmd.CombinedOutput()
if err != nil {
logger.Error(err)
return nil, err
}
time.Sleep(time.Second * time.Duration(5))
//目前openwrt上似乎不是安裝的arp指令,而是軟連結的檢視該檔案,是以arp指令實際上應該是如下内容
cmd = exec.Command("cat", "/proc/1/net/arp")
output, err = cmd.Output()
if err != nil {
logger.Error(err)
return nil, err
}
logger.Debug(string(output))
var res []string
scanner := bufio.NewScanner(strings.NewReader(string(output)))
for scanner.Scan() {
logger.Debug(scanner.Text())
if strings.Contains(scanner.Text(), devName) {
tmp := strings.Split(scanner.Text(), " ")
res = append(res, tmp[0])
}
}
return res, nil
}