【问题标题】:Getting ipv6 subnet mask from net.CIDRMask从 net.CIDRMask 获取 ipv6 子网掩码
【发布时间】:2016-02-19 13:59:48
【问题描述】:

我正在编写代码,并尝试添加 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

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

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

func CIDRMask(ones, bits int) IPMask

CIDRMask 返回一个 IPMask,由 `ones' 1 位后跟 0s 最多为“位”位的总长度。对于这种形式的掩码,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   } ]

提前致谢!

【问题讨论】:

  • 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,那么是的,它可以满足您的需求。

标签: go ipv6


【解决方案1】:

我不确定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)。由于这些每次都是完全相同的计算,因此您可以选择简单地将值设置为代码中的常量。正确的值是:

【讨论】:

  • PrefixLength 是我将用于ones 的值,并且是从 govc api 调用返回的,json 在上面。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2020-09-05
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多