Go-OpenWrt获取wan口ip、dns、网关ip

2023-11-05

Go-OpenWrt获取wan口ip、dns、网关ip


1. 前言

一般来说,Openwrt可以配置多个wan口和多个lan口,这里获取的wan口的ip、dns等信息是基于知道wan口名称的前提下使用ifstatus命令来获取解析结果的。

2. 解决方案思路

通过uci命令获取相关网络接口名称,然后利用ifstatus查看对应接口的网络信息后获取,当然也可以直接通过uci接口获取:

root@OpenWrt:~# uci show network
network.loopback=interface
network.loopback.ifname='lo'
network.loopback.proto='static'
network.loopback.ipaddr='127.0.0.1'
network.loopback.netmask='255.0.0.0'
network.globals=globals
network.globals.ula_prefix='fdcd:b3fe:8353::/48'
network.lan=interface
network.lan.type='bridge'
network.lan.proto='static'
network.lan.netmask='255.255.255.0'
network.lan.ip6assign='60'
network.lan.ipaddr='40.40.40.100'
network.lan.ifname='eth1 eth2 eth3 eth4'
network.wan=interface
network.wan.ifname='eth7'
network.wan.proto='dhcp'
network.wan_eth=interface
network.wan_eth.ifname='eth0'
network.wan_eth.proto='static'
network.wan_eth.netmask='255.255.255.0'
network.wan_eth.gateway='192.168.67.254'
network.wan_eth.dns='8.8.8.8'
network.wan_eth.ipaddr='192.168.67.87'
network.SFP1=interface
network.SFP1.ifname='eth5'
network.SFP1.proto='static'
network.SFP1.netmask='255.255.255.0'
network.SFP1.dns='8.8.8.8'
network.SFP1.ipaddr='192.168.67.88'
network.SFP1.gateway='192.168.67.1'
root@OpenWrt:~# uci show network.SFP1.ipaddr
network.SFP1.ipaddr='192.168.67.88'
root@OpenWrt:~# ifstatus SFP1
{
        "up": true,
        "pending": false,
        "available": true,
        "autostart": true,
        "dynamic": false,
        "uptime": 1629,
        "l3_device": "eth5",
        "proto": "static",
        "device": "eth5",
        "updated": [
                "addresses",
                "routes"
        ],
        "metric": 0,
        "dns_metric": 0,
        "delegation": true,
        "ipv4-address": [
                {
                        "address": "192.168.67.88",
                        "mask": 24
                }
        ],
        "ipv6-address": [

        ],
        "ipv6-prefix": [

        ],
        "ipv6-prefix-assignment": [

        ],
        "route": [
                {
                        "target": "0.0.0.0",
                        "mask": 0,
                        "nexthop": "192.168.67.1",
                        "source": "0.0.0.0/0"
                }
        ],
        "dns-server": [
                "8.8.8.8"
        ],
        "dns-search": [

        ],
        "neighbors": [

        ],
        "inactive": {
                "ipv4-address": [

                ],
                "ipv6-address": [

                ],
                "route": [

                ],
                "dns-server": [

                ],
                "dns-search": [

                ],
                "neighbors": [

                ]
        },
        "data": {

        }
}

所以看使用场景决定使用哪种方式,对于OpenWrt来说uci是非常方便且实用的,所以遇到一些问题时首先考虑uci方式是否可行。

3. 代码

uci方式就不说了,利用相关语言的uci库进行处理即可,实在不行调用shell执行uci命令处理也可以,算是比较简单,这里就不多说了,这里主要给一下实用ifstatus命令获取信息的代码,也是通过ifstatus命令执行后将结果进行处理,由于结果为json形式,所以处理起来是比较方便的(给一个json转go结构体的网站,很方便:https://mholt.github.io/json-to-go/):

type ifStatus struct {
    Up          bool     `json:"up"`
    Pending     bool     `json:"pending"`
    Available   bool     `json:"available"`
    Autostart   bool     `json:"autostart"`
    Dynamic     bool     `json:"dynamic"`
    Uptime      int      `json:"uptime"`
    L3Device    string   `json:"l3_device"`
    Proto       string   `json:"proto"`
    Device      string   `json:"device"`
    Updated     []string `json:"updated"`
    Metric      int      `json:"metric"`
    DNSMetric   int      `json:"dns_metric"`
    Delegation  bool     `json:"delegation"`
    Ipv4Address []struct {
        Address string `json:"address"`
        Mask    int    `json:"mask"`
    } `json:"ipv4-address"`
    Ipv6Address          []interface{} `json:"ipv6-address"`
    Ipv6Prefix           []interface{} `json:"ipv6-prefix"`
    Ipv6PrefixAssignment []interface{} `json:"ipv6-prefix-assignment"`
    Route                []struct {
        Target  string `json:"target"`
        Mask    int    `json:"mask"`
        Nexthop string `json:"nexthop"`
        Source  string `json:"source"`
    } `json:"route"`
    DNSServer []string      `json:"dns-server"`
    DNSSearch []interface{} `json:"dns-search"`
    Neighbors []interface{} `json:"neighbors"`
    Inactive  struct {
        Ipv4Address []interface{} `json:"ipv4-address"`
        Ipv6Address []interface{} `json:"ipv6-address"`
        Route       []interface{} `json:"route"`
        DNSServer   []interface{} `json:"dns-server"`
        DNSSearch   []interface{} `json:"dns-search"`
        Neighbors   []interface{} `json:"neighbors"`
    } `json:"inactive"`
    Data struct {
        Leasetime int `json:"leasetime"`
    } `json:"data"`
}

type WanInfo struct {
    Ipv4Address string
    Gateway     string
    DNS1        string
    DNS2        string
}

func GetWanIpDNSGateway(wanName string) (*WanInfo, error) {
    cmd := exec.Command("ifstatus", wanName)
    output, err := cmd.CombinedOutput()
    if err != nil {
        logger.Error(err)
        return nil, err
    }
    logger.Debug(string(output))
    jsonRes := ifStatus{}
    err = json.Unmarshal(output, &jsonRes)
    if err != nil {
        logger.Error(err)
        return nil, err
    }
    wanInfo := &WanInfo{}
    wanInfo.Ipv4Address = jsonRes.Ipv4Address[0].Address
    wanInfo.Gateway = jsonRes.Route[0].Nexthop
    for i := 0; i < len(jsonRes.DNSServer); i++ {
        switch i {
        case 0:
            wanInfo.DNS1 = jsonRes.DNSServer[0]
        case 1:
            wanInfo.DNS2 = jsonRes.DNSServer[1]
        }
    }
    return wanInfo, nil
}
//一般就是uci中查找出来的network中interfaced的wan口名称
wanInfo, err := utils.GetWanIpDNSGateway(interfaceWan)
    if err != nil {
        logger.Error(err)
        return nil, err
    }
    res.Ipaddr = wanInfo.Ipv4Address
    res.Gateway = wanInfo.Gateway
    if wanInfo.DNS1 != "" {
        res.Dns1 = wanInfo.DNS1
    }
    if wanInfo.DNS2 != "" {
        res.Dns2 = wanInfo.DNS2
    }
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

Go-OpenWrt获取wan口ip、dns、网关ip 的相关文章

  • 错误:NVIDIA-SMI 失败,因为无法与 NVIDIA 驱动程序通信

    NVIDIA SMI 抛出此错误 NVIDIA SMI 失败 因为无法与 NVIDIA 通信 司机 确保安装了最新的 NVIDIA 驱动程序并且 跑步 我清除了 NVIDIA 并按照提到的步骤重新安装了它here https askubun
  • Linux命令列出所有可用命令和别名

    是否有一个 Linux 命令可以列出该终端会话的所有可用命令和别名 就好像您输入 a 并按下 Tab 键一样 但针对的是字母表中的每个字母 或者运行 别名 但也返回命令 为什么 我想运行以下命令并查看命令是否可用 ListAllComman
  • 检查值是否实现接口的说明

    我读过 Effective Go 和其他类似这样的问答 golang接口合规性编译类型检查 https stackoverflow com questions 17994519 golang interface compliance com
  • 如何通过代理将套接字连接到http服务器?

    最近 我使用 C 语言编写了一个程序 用于连接到本地运行的 HTTP 服务器 从而向该服务器发出请求 这对我来说效果很好 之后 我尝试使用相同的代码连接到网络上的另一台服务器 例如 www google com 但我无法连接并从网络中的代理
  • 在 Go 中跟踪 HTTP 请求时指定超时

    我知道通过执行以下操作来指定 HTTP 请求超时的常用方法 httpClient http Client Timeout time Duration 5 time Second 但是 我似乎不知道在跟踪 HTTP 请求时如何执行相同的操作
  • 如何从类似于 eclipse 的命令行创建可运行的 jar 文件

    我知道 eclipse 会生成一个可运行的 jar 文件 其中提取并包含在该 jar 文件中的所有库 jar 文件 从命令提示符手动创建 jar 文件时如何执行类似的操作 我需要将所有 lib jar 解压到类文件夹中吗 目前我正在使用 j
  • 为 Linux 安装 R 包时出错

    我试图在 R 3 3 上安装一个名为 rgeos 的包 但是当我输入 install packages rgeos 但它返回给我以下错误 其他包也会发生同样的情况 但不是所有包 gt installing source package rg
  • 如何解析 Content-Disposition 标头以检索文件名属性?

    使用 go 如何解析从 http HEAD 请求检索到的 Content Disposition 标头以获取文件的文件名 此外 如何从 http HEAD 响应中检索标头本身 这样的事情正确吗 resp err http Head http
  • 操作系统什么时候清除进程的内存

    进程在某些操作系统上成功或异常终止 操作系统何时决定擦除分配给该进程的内存 数据 代码等 在退出时或当它想为新进程分配内存时 这个清除内存分配过程在所有操作系统 winXP Win7 linux Mac 上都相同吗 据我了解 页表具有该进程
  • 如何用X11复制到剪贴板?

    使用 OS X 上的框架 我可以使用以下命令将 PNG 复制到粘贴板 在 C 中 显然我可以将 NSPasteboard 与 Cocoa 一起使用 include
  • 怎样才能使 Windows 成为一个开箱即用的 POSIX 兼容操作系统?

    这个问题的动机是我的一个牵强的梦想 即 nix 平台上可用的许多优秀软件可以轻松移植到 Windows 微软最近对开源和开放性采取了不同的方法 所以我真的很想知道如果微软有这样的倾向 这样的事情会有多可行 我很好奇的一些更具体的事情是 是否
  • gethostbyname() 或 getnameinfo() 如何在后台工作?

    How gethostbyname or getnameinfo 在后台工作 include
  • 在 LINUX 上使用 Python 连接到 OLAP 多维数据集

    我知道如何在 Windows 上使用 Python 连接到 MS OLAP 多维数据集 嗯 至少有一种方法 通常我使用 win32py 包并调用 COM 对象进行连接 import win32com client connection wi
  • 标准头文件中的 C 编译器错误 - 未定义的 C++ 定义

    我正在尝试编译 C 程序 但收到许多错误 这些错误是在标准 C 头文件 inttypes h stdio h stat h 等 中遇到的 错误的来源是以下未定义的常量 BEGIN DECLS END DECLS BEGIN NAMESPAC
  • 在Linux中断上下文中运行用户线程

    我正在编写一些定制的应用程序 并允许更改 Linux 内核中的中断处理程序代码 我有一个用户线程正在等待中断发生 如果发生中断 那么我要做的第一件事就是执行该用户线程 有什么办法让它发挥作用吗 Thanks 创建一个字符设备 这就是内核所做
  • 如何以编程方式从Linux中的进程名称获取进程ID

    在我的项目中 我们使用 ACE 自适应通信环境 中间件来编写可在 Windows 和 Linux 上运行的独立于操作系统的代码 要求是从进程名称中获取进程 ID 由于 ACE 不支持这一点 因此我们必须使用特定于平台的宏来分离 Window
  • Linux shell 脚本:十六进制数字到二进制字符串

    我正在 shell 脚本中寻找一些简单的方法来将十六进制数字转换为 0 和 1 字符的序列 Example 5F gt 01011111 是否有任何命令或简单的方法来完成它 或者我应该为其编写一些开关 echo ibase 16 obase
  • linux x86 汇编语言 sys_read 调用的第一个参数应为 0 (stdin)

    我正在编写一个简单的汇编程序来从标准输入读取 如 scanf 这是我的代码 section bss num resb 5 section txt global start start mov eax 3 sys read mov ebx 0
  • 适用于 KDE 和 Gnome 的 Gui [重复]

    这个问题在这里已经有答案了 我想为一个现在是 CLI 的应用程序编写一个 gui 它需要在 KDE 和 Gnome DE 中 看起来不错 充分利用用户的外观设置 如果我选择 Qt 或 GTK 我能够做到这一点吗 它们与两个 DE 集成良好吗
  • 匿名结构和空结构

    http play golang org p vhaKi5uVmm http play golang org p vhaKi5uVmm package main import fmt var battle make chan string

随机推荐