Networking 我可以使用什么系统调用/方法来获取默认网络网关

Networking 我可以使用什么系统调用/方法来获取默认网络网关,networking,go,system-calls,Networking,Go,System Calls,使用什么软件包、本机函数、syscall可以用来获取服务器上的默认网关 我希望避免创建arround、route、ip等命令的包装器,或者读取、解析现有文件,其想法是以最可行的方式获取值 例如,这是命令的输出: $route-n获取默认值 路由到:默认值 目的地:默认值 掩码:默认值 网关:192.168.1.1 接口:en1 旗帜: recvpipe发送管道ssthresh rtt,毫秒rttvar跃点计数mtu到期 0 0 0 0

使用什么软件包、本机函数、syscall可以用来获取服务器上的默认网关

我希望避免创建arround、route、ip等命令的包装器,或者读取、解析现有文件,其想法是以最可行的方式获取值

例如,这是命令的输出:

$route-n获取默认值
路由到:默认值
目的地:默认值
掩码:默认值
网关:192.168.1.1
接口:en1
旗帜:
recvpipe发送管道ssthresh rtt,毫秒rttvar跃点计数mtu到期
0         0         0         0         0         0      1500         0

为了打印/获取网关地址/接口,我想做一些简单的事情。

一个选项是读取
/proc/net/route
。在我的一个系统上,它包含:

Iface   Destination Gateway     Flags   RefCnt  Use Metric  Mask        MTU Window  IRTT                                                       
team0   00000000    010017BA    0003    0   0   0   00000000    0   0   0                                                                              
team0   0000070A    00000000    0001    0   0   0   00FEFFFF    0   0   0                                                                              

您可以在中读取,通过一些文本处理捕获网关,并将十六进制字符串转换为net.IP。有点狭义,但我在std库或其他地方找不到任何包可以为您访问它。

对于Linux,您可以使用captncraig建议的procfs。下面是一个提取网关地址并将其转换为四点ipV4的代码段

/* /proc/net/route file:
Iface   Destination Gateway     Flags   RefCnt  Use Metric  Mask
eno1    00000000    C900A8C0    0003    0   0   100 00000000    0   00                                                                             
eno1    0000A8C0    00000000    0001    0   0   100 00FFFFFF    0   00 
*/

const (
    file  = "/proc/net/route"
    line  = 1    // line containing the gateway addr. (first line: 0)
    sep   = "\t" // field separator
    field = 2    // field containing hex gateway address (first field: 0)
)

func main() {

    file, err := os.Open(file)
    if err != nil {
        log.Fatal(err)
    }
    defer file.Close()

    scanner := bufio.NewScanner(file)
    for scanner.Scan() {

        // jump to line containing the agteway address
        for i := 0; i < line; i++ {
            scanner.Scan()
        }

        // get field containing gateway address
        tokens := strings.Split(scanner.Text(), sep)
        gatewayHex := "0x" + tokens[field]

        // cast hex address to uint32
        d, _ := strconv.ParseInt(gatewayHex, 0, 64)
        d32 := uint32(d)

        // make net.IP address from uint32
        ipd32 := make(net.IP, 4)
        binary.LittleEndian.PutUint32(ipd32, d32)
        fmt.Printf("%T --> %[1]v\n", ipd32)

        // format net.IP to dotted ipV4 string
        ip := net.IP(ipd32).String()
        fmt.Printf("%T --> %[1]v\n", ip)

        // exit scanner
        break
    }
}
/*/proc/net/route文件:
Iface目标网关标志RefCnt使用度量掩码
eno1 00000000 C900A8C00003 00 00000000
eno1 0000A8C000000000 0001 0 100 00 FFFFFF 0 00
*/
常数(
file=“/proc/net/route”
line=1//包含网关地址的行。(第一行:0)
sep=“\t”//字段分隔符
field=2//包含十六进制网关地址的字段(第一个字段:0)
)
func main(){
文件,错误:=os.Open(文件)
如果错误!=零{
log.Fatal(错误)
}
延迟文件。关闭()
扫描程序:=bufio.NewScanner(文件)
对于scanner.Scan(){
//跳转到包含agteway地址的行
对于i:=0;i%[1]v\n”,ipd32)
//将net.IP格式化为虚线ipV4字符串
ip:=net.ip(ipd32.String())
fmt.Printf(“%T-->%[1]v\n”,ip)
//出口扫描仪
打破
}
}

示例代码snip:

rifs := nettest.RoutedInterface("ip", net.FlagUp | net.FlagBroadcast)
if rifs != nil {
    fmt.Println("Routed interface is ",rifs.HardwareAddr.String())
    fmt.Println("Flags are", rifs.Flags.String())
}

注意:您需要将golang代码复制到本地库中,因为不允许直接进行/内部调用。

是否
net.Interfaces()
包含网关@dm03514我不相信。出于好奇,你为什么需要它?@captncaig在使用VP时知道/打印默认网关路由这似乎是在linux上,但是Unix(freebsd、mac os等)呢?我想要一些操作系统不可知的东西。这是我想要避免的事情,我想知道一些系统调用,以使这更适合操作系统agnostic@nbari:系统调用不会使其变得更不依赖操作系统,系统调用更依赖于系统。每个操作系统都有自己的工具,您需要使用这些工具。您可能会找到
netstat
命令的一些子集,这些子集将在大多数操作系统上打印路由表,否则只需为每个操作系统调用相应的命令即可。@JimB我使用系统调用的目标是,尽管我必须维护它们,并且交叉编译是为了避免依赖外部命令,通过这种方式,我可以生成一个二进制文件,它在几乎所有系统上的行为都是相同的。如果它使用系统调用或执行某些操作,那么它们同样是不可移植的。只需执行操作系统上可用的工具即可。导入会很好;)不知道为什么会被接受,因为问题是关于网关IP的。如果查看interface.go链接,代码对网关没有任何作用;它只是检查本地接口上的地址并返回一个它满意的地址。我无法使用nettest包检索接口的网关IP。你能说得更具体些吗?
rifs := nettest.RoutedInterface("ip", net.FlagUp | net.FlagBroadcast)
if rifs != nil {
    fmt.Println("Routed interface is ",rifs.HardwareAddr.String())
    fmt.Println("Flags are", rifs.Flags.String())
}