openwrt利用arp获取局域网设备IP

2023-11-18

openwrt利用arp获取局域网设备IP


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.3IEEE 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
}

编译运行于openwrt后结果如下:

在这里插入图片描述

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

openwrt利用arp获取局域网设备IP 的相关文章