Networking 如何从go中的本地接口获取所有地址和掩码?

Networking 如何从go中的本地接口获取所有地址和掩码?,networking,go,ip,ip-address,Networking,Go,Ip,Ip Address,如何从golang的本地接口获取所有地址和掩码 我需要与每个IP地址一起配置实际的网络掩码 此代码不显示Windows 7中的网络掩码: package main import ( "fmt" "log" "net" ) func localAddresses() { ifaces, err := net.Interfaces() if err != nil { log.Print(fmt.Errorf("localAddresses:

如何从golang的本地接口获取所有地址和掩码

我需要与每个IP地址一起配置实际的网络掩码

此代码不显示Windows 7中的网络掩码:

package main

import (
    "fmt"
    "log"
    "net"
)

func localAddresses() {
    ifaces, err := net.Interfaces()
    if err != nil {
        log.Print(fmt.Errorf("localAddresses: %v\n", err.Error()))
        return
    }
    for _, i := range ifaces {
        addrs, err := i.Addrs()
        if err != nil {
            log.Print(fmt.Errorf("localAddresses: %v\n", err.Error()))
            continue
        }
        for _, a := range addrs {
            log.Printf("%v %v\n", i.Name, a)
        }
    }
}

func main() {
    localAddresses()
}

更新:此问题已在Go中修复:

网络接口可能具有多种类型的地址。
Addr
只是一个可能包含
net.IPAddr
的接口。但通过类型断言或类型开关,您可以访问实际地址类型:

package main

import (
    "fmt"
    "net"
)

func localAddresses() {
    ifaces, err := net.Interfaces()
    if err != nil {
        fmt.Print(fmt.Errorf("localAddresses: %+v\n", err.Error()))
        return
    }
    for _, i := range ifaces {
        addrs, err := i.Addrs()
        if err != nil {
            fmt.Print(fmt.Errorf("localAddresses: %+v\n", err.Error()))
            continue
        }
        for _, a := range addrs {
            switch v := a.(type) {
            case *net.IPAddr:
                fmt.Printf("%v : %s (%s)\n", i.Name, v, v.IP.DefaultMask())
            }

        }
    }
}

func main() {
    localAddresses()
}
编辑

不幸的是,
net
包没有返回地址的掩码。因此,您必须执行
net
包所做的低级系统调用。下面的代码是一个示例,但仍然需要对ip和掩码进行解析:

package main

import (
    "fmt"
    "net"
    "os"
    "syscall"
    "unsafe"
)

func getAdapterList() (*syscall.IpAdapterInfo, error) {
    b := make([]byte, 1000)
    l := uint32(len(b))
    a := (*syscall.IpAdapterInfo)(unsafe.Pointer(&b[0]))
    // TODO(mikio): GetAdaptersInfo returns IP_ADAPTER_INFO that
    // contains IPv4 address list only. We should use another API
    // for fetching IPv6 stuff from the kernel.
    err := syscall.GetAdaptersInfo(a, &l)
    if err == syscall.ERROR_BUFFER_OVERFLOW {
        b = make([]byte, l)
        a = (*syscall.IpAdapterInfo)(unsafe.Pointer(&b[0]))
        err = syscall.GetAdaptersInfo(a, &l)
    }
    if err != nil {
        return nil, os.NewSyscallError("GetAdaptersInfo", err)
    }
    return a, nil
}

func localAddresses() error {
    ifaces, err := net.Interfaces()
    if err != nil {
        return err
    }

    aList, err := getAdapterList()
    if err != nil {
        return err
    }

    for _, ifi := range ifaces {
        for ai := aList; ai != nil; ai = ai.Next {
            index := ai.Index

            if ifi.Index == int(index) {
                ipl := &ai.IpAddressList
                for ; ipl != nil; ipl = ipl.Next {

                    fmt.Printf("%s: %s (%s)\n", ifi.Name, ipl.IpAddress, ipl.IpMask)
                }
            }
        }
    }
    return err
}

func main() {
    err := localAddresses()
    if err != nil {
        panic(err)
    }
}

一些代码无耻地借用了interface_windows.go。即使是评论也保持原封不动

这应该会给你提供你想要的
ipnet

ip, ipnet, err := net.ParseCIDR(a.String())

我知道这篇针对Windows7的帖子,但如果你使用MacOSX,希望这能对你有所帮助

只需调用
GetNetMask(“en0”)


我正在修改@ANisus answer并获得所有界面和掩码(在Windows 10和WSL上测试)(Microsoft Ubuntu 16.04.5 LTS):


我需要的是实际的掩码,而不是类的默认值。我看到类型net.IPNet提供net.IPNet.mask。有没有办法将地址读取为net.IPNet呢?查看
net
包的文档/源代码,我看到它们只提供IP。因此,您需要使用
syscall
包。我将更新我的回答。很好!但是它只显示一个界面的地址/掩码。修复:请更新答案,然后我接受它!谢谢。@Everton啊,是的。我看到了我的错误。我用你的错误修复更新了代码。欢迎:)syscall.ipadapternfo在Go 1.5上有一些问题,它将在Go 1.6中修复。参考github.com/golang/go/issues/12551
func GetNetMask(deviceName string) string {
    switch runtime.GOOS {
    case "darwin":
        cmd := exec.Command("ipconfig", "getoption", deviceName, "subnet_mask")
        out, err := cmd.CombinedOutput()
        if err != nil {
            return ""
        }

        nm := strings.Replace(string(out), "\n", "", -1)
        log.Println("netmask=", nm, " OS=", runtime.GOOS)
        return nm
    default:
        return ""
    }
    return ""
}
package main

import (
    "fmt"
    "net"
)

func localAddresses() {
    ifaces, err := net.Interfaces()
    if err != nil {
        fmt.Print(fmt.Errorf("localAddresses: %+v\n", err.Error()))
        return
    }
    for _, i := range ifaces {
        addrs, err := i.Addrs()
        if err != nil {
            fmt.Print(fmt.Errorf("localAddresses: %+v\n", err.Error()))
            continue
        }
        for _, a := range addrs {
            switch v := a.(type) {
            case *net.IPAddr:
                fmt.Printf("%v : %s (%s)\n", i.Name, v, v.IP.DefaultMask())

            case *net.IPNet:
                fmt.Printf("%v : %s [%v/%v]\n", i.Name, v, v.IP, v.Mask)
            }

        }
    }
}

func main() {
    localAddresses()
}