从net.CIDRMask获取IPv6子网掩码。

huangapple go评论96阅读模式
英文:

Getting ipv6 subnet mask from net.CIDRMask

问题

我正在处理代码,并尝试添加IPv6支持。以下代码是当前代码库中用于IPv4支持的代码。该代码接收一个IPv4地址,并获取该地址在/32子网掩码上的子网掩码。

// IP地址字符串
networkInterface["ip_address"] = v.IpAddress[0]
m := net.CIDRMask(v.IpConfig.IpAddress[0].PrefixLength, 32)
subnetMask := net.IPv4(m[0], m[1], m[2], m[3])
networkInterface["subnet_mask"] = subnetMask.String()

我知道net.CIDRMask可以用于IPv6,但我不确定如何在IPv6地址上使用它。

我现在正在测试IP地址,以确定地址是IPv4还是IPv6:

testInput := net.ParseIP(v.IpAddress[0])
if testInput.To4() != nil {
    // 找到IPv4子网掩码
}
if testInput.To16() != nil {
    // 进行IPv6子网掩码
}

net.CIDRMask的单元测试中有使用IPv6的示例,可以在这里找到:https://golang.org/src/net/ip_test.go

但这超出了我的Golang经验和IPv6知识范围。

在阅读文档 https://golang.org/pkg/net/#CIDRMask 时,我发现以下内容:

func CIDRMask(ones, bits int) IPMask

> CIDRMask返回一个由'ones'个1位和0位组成的IPMask总长度为'bits'对于这种形式的掩码CIDRMask是IPMask.Size的反函数

那么,我应该使用什么值作为onesbits

这是从API返回的内容:

$ govc vm.info -json vcsa | jq .VirtualMachines[0].Guest.Net[0].IpConfig.IpAddress
[
    {
        "IpAddress": "10.20.128.218",
        "PrefixLength": 22,
        "Origin": "",
        "State": "preferred",
        "Lifetime": null
    }
]

提前感谢!

英文:

I am working on code, and trying to add ipv6 support. The following code is in the current code base for ipv4 support. The code takes a ipv4 ip address and gets the subnet mask for the address on a /32.

// string of ip address
networkInterface["ip_address"] = v.IpAddress[0]
m := net.CIDRMask(v.IpConfig.IpAddress[0].PrefixLength, 32)
subnetMask := net.IPv4(m[0], m[1], m[2], m[3])
networkInterface["subnet_mask"] = subnetMask.String()

I know that net.CIDRMask works with ipv6, I am uncertain how to use it with an ipv6 address.

I am now testing the ip address to determine if the address is ipv4 or ipv6:

testInput := net.ParseIP(v.IpAddress[0])
if testInput.To4() != nil {
// find ipv4 subnet mask
}
if testInput.To16() != nil {
// do ipv6 subnet mask
}

The unit tests for net.CIDRMask have examples working with ipv6 located here: https://golang.org/src/net/ip_test.go

But it is beyond both my golang experience and ipv6 knowledge.

While RTFM'ing the docs https://golang.org/pkg/net/#CIDRMask mention:

func CIDRMask(ones, bits int) IPMask

> CIDRMask returns an IPMask consisting of `ones' 1 bits followed by 0s
> up to a total length of `bits' bits. For a mask of this form, CIDRMask
> is the inverse of IPMask.Size.

So what values do I use for ones and bits?

This is what is comming back from the api:

$ govc vm.info -json vcsa | jq .VirtualMachines[0].Guest.Net[0].IpConfig.IpAddress [   {
    "IpAddress": "10.20.128.218",
    "PrefixLength": 22,
    "Origin": "",
    "State": "preferred",
    "Lifetime": null   } ]

Thanks in advance!

答案1

得分: 1

我不确定PrefixLength是什么,它可能是在你的某个结构体中定义的字段,但在net包或标准库的任何地方都没有出现过:https://golang.org/search?q=PrefixLength。

所以我不确定PrefixLength应该返回什么,但是我可以告诉你:

  • IPv4地址由32位数据组成(共256 x 256 x 256 x 256个IP),因此在处理IPv4时,传递给net.CIDRMaskbits参数的值应为32。
  • IPv6地址由128位数据组成,因此bits参数的值为128。
  • 对于与单个IP对应的CIDR范围的子网掩码,将具有最大数量的1,因此ones的值为32或128,具体取决于你是否在讨论IPv4或IPv6。

因此,对于IPv4,你应该调用net.CIDRMask(32, 32),对于IPv6,调用net.CIDRMask(128, 128)。由于这些计算每次都是相同的,你可以选择在代码中提前将这些值设置为常量。正确的值为:

  • 对于IPv4:https://golang.org/src/net/ip_test.go#L307
  • 对于IPv6:https://golang.org/src/net/ip_test.go#L311
英文:

I'm not sure what PrefixLength is, it may be some field defined in one of your structs, but it doesn't appear to be a field on anything in the net package, or in fact anywhere in the standard library: https://golang.org/search?q=PrefixLength.

So I'm not sure what PrefixLength is expected to give, but, I can tell you:

  • IPv4 addresses consist of 32 bits of data (256 x 256 x 256 x 256 total IPs), so when dealing with IPv4, the value for the bits argument to net.CIDRMask should be 32.
  • IPv4 addresses have 128 bits of data, so the bits argument is 128.
  • The subnet mask for a CIDR range corresponding to a single IP will have the maximum number of ones, so the ones value is 32 or 128, depending on whether you're talking IPv4 or IPv6.

Therefore, for IPv4, you should call net.CIDRMask(32, 32), and for IPv6, net.CIDRMask(128, 128). Since these will be the exact same calculations every time, you have the option to simply set the values up front as constants in your code. The correct values are:

huangapple
  • 本文由 发表于 2015年11月18日 08:37:06
  • 转载请务必保留本文链接:https://go.coder-hub.com/33769800.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定