Networking 如何从go中的本地接口获取所有地址和掩码?
如何从golang的本地接口获取所有地址和掩码 我需要与每个IP地址一起配置实际的网络掩码 此代码不显示Windows 7中的网络掩码: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:
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()
}