我正在编写代码,并尝试添加ipv6支持。 以下代码是ipv4支持的当前代码库。 该代码获取一个ipv4 ip地址,并在/ 32上获取该地址的子网掩码。

1
2
3
4
5
// 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:

1
2
3
4
5
6
7
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

但这超出了我的golang经验和ipv6知识。

在RTFM为文档https://golang.org/pkg/net/#CIDRMask提及时:

1
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.

那么我对onesbits使用什么值?

这是从api返回的内容:

1
2
3
4
5
6
$ 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   } ]

提前致谢!

  • bits对于IPv6是128,对于IPv4是32。对于ones,这取决于,不是100%清楚您要尝试做什么。您是否要获取代表1个单个IP的CIDR的子网掩码?如果是这样,则ones应该等于bits。此外,如果您总是要使用相同的两对输入来调用函数,为什么不只是一次对它们进行一次输入呢?
  • 我正在尝试为单个IP地址获取子网掩码。让我更加清楚...我认为这就是代码的作用。新手到golang :)
  • 任何单个IPv4地址的子网掩码将始终是您在307行看到的地址:golang.org/src/net/ip_test.go#L307。对于IPv6,它始终是您在311行上看到的内容:golang.org/src/net/ip_test.go#L311。
  • 因此,我不应该重新计算它,创建一个常量并重用它。但是现在我很困惑。代码是否按照预期的方式工作?
  • 很难说出代码在做什么,因为您没有提供可以运行的最小示例。我不知道v是什么,或者v.IpConfig.IpAddress[0].PrefixLength往往是什么,但是如果后者是32,则可以,它可以满足您的要求。
  • 因此,看起来应该像以前一样是前缀长度。更新的问题。 @AmitKumarGupta您可以添加一个答案,以便我给您一些已回答的问题吗?

我不确定PrefixLength是什么,它可能是在您的一个结构中定义的某个字段,但它似乎不是net包中任何内容的字段,或者实际上不是标准库中的任何字段:https://golang.org/search?q=PrefixLength。

因此,我不确定应该提供什么PrefixLength,但是,我可以告诉您:

  • IPv4地址包含32位数据(总共256 x 256 x 256 x 256个IP),因此在处理IPv4时,net.CIDRMaskbits参数的值应为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
  • PrefixLength是我将用于ones的值,并且从govc api调用返回,上面是json。