我正在编写代码,并尝试添加ipv6支持。以下代码位于ipv4支持的当前代码库中。该代码获取ipv4 ip地址,并获取/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()
我知道net.CIDRMask
适用于ipv6,我不确定如何将其与ipv6地址一起使用。
我现在正在测试ip地址,以确定地址是ipv4还是ipv6:
testInput := net.ParseIP(v.IpAddress[0])
if testInput.To4() != nil {
// find ipv4 subnet mask
}
if testInput.To16() != nil {
// do ipv6 subnet mask
}
net.CIDRMask
的单元测试有一些使用ipv6的示例,位于此处:https://golang.org/src/net/ip_test.go
但这超出了我的高尔夫经验和ipv6知识。
RTF处理文档时https://golang.org/pkg/net/#CIDRMask提及:
func CIDRMask(ones, bits int) IPMask
CIDRMask返回一个IPMask,该IPMask由"ones"1位后跟0组成最高可达"位"位的总长度。对于这种形式的掩码,CIDRMask是IPMask.Size.的倒数
那么,我对ones
和bits
使用什么值呢?
这就是从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 } ]
提前感谢!
我不确定PrefixLength
是什么,它可能是在您的结构中定义的某个字段,但它似乎不是net
包中任何东西上的字段,实际上也不是标准库中的任何地方:https://golang.org/search?q=PrefixLength.
所以我不确定PrefixLength
会给出什么,但是,我可以告诉你:
- IPv4地址由32位数据组成(总IP为256 x 256 x 256×256),因此在处理IPv4时,
net.CIDRMask
的bits
参数的值应为32 - IPv4地址有128位数据,因此
bits
参数为128 - 与单个IP对应的CIDR范围的子网掩码将具有最大个数,因此
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