65.9K
CodeProject 正在变化。 阅读更多。
Home

IPv6 子网划分 第 1/2 部分

starIconstarIconstarIconstarIconstarIcon

5.00/5 (19投票s)

2013年9月28日

BSD

7分钟阅读

viewsIcon

57966

在本文中,我将通过示例来解释 IPv6 子网划分的工作原理。

引言

我们正处于从 IPv4 到 IPv6 寻址结构的过渡阶段,我相信网络工程师应该能够轻松无误地规划他们的 IPv6 寻址/子网划分基础设施。在本文中,我试图通过示例来解释 IPv6 子网划分的工作原理。

我还编写并发布了一个免费的 IPv6 子网划分工具/计算器,同时支持 C# 和 Java JDK 17 应用程序框架。它可以让你规划/划分分配给你所有的 128 位地址。你可以在本文的第二部分找到这些应用程序。

我分发这些应用程序是希望它们能对你的子网计算有所帮助。我将努力持续开发该软件,所以请不要犹豫,就任何错误或新功能建议发表评论/提供信息。

1. IPv6 中的 “/”(斜杠或前缀长度表示法)是如何工作的?

“/” 表示你的子网固定不变的位数。固定不变意味着你无法控制这些位,你不能改变它们(我喜欢称它们为“只看不动的位”)。IPv6 地址为 128 位长,你的网络/组织被分配的地址中,“128 减去 /前缀长度值”的这些位是属于你控制的。你可以用这些位进行子网划分,并将地址分配给你的计算机/汽车/手机/等。

例如,假设你的服务提供商(或 RIPE、ARIN 等)为你分配了前缀 '2001:db8:1234::/48'。在这种情况下,/48 表示从最左边的位到第 48 位(包括第 48 位)是固定的,不能改变(只看不动)。其余的位,即 128-48=80 位,归你控制,用于寻址和子网划分。

因此,“/”前缀长度的重要性在于它指示了你的网络边界。换句话说,你的分配网络从哪个数字开始,到哪个数字结束。

2. 查找我们子网的 IPv6 起始地址和结束地址

如果我们有一个例如 192.168.3.0/24 的子网前缀,那么 24 位是固定的。你不能改变这些位。我们的子网掩码将是 255.255.255.0,我们可以通过使用 32-24=8 位来进行子网划分,同时注意子网地址和广播地址,这就像我们在 IPv4 经验中非常熟悉的那样。

2.1 三个有用的位运算符:& , | , ~

& (AND)、| (OR)、~ (NOT 或位反转器):我们将使用这三个位运算符进行计算。我认为每个人(至少从大学数字逻辑课程中)都熟悉它们的操作方式。我不会在这里再次详细解释。你可以搜索“位运算符”以获取更多信息。

现在,有了分配给我们的 IPv6 子网前缀,我们如何找到我们的子网以及它的起始和结束地址?我们可以借助这三个逻辑运算符轻松计算它们,如下所示。我将尝试同时在 IPv4 和 IPv6 上演示。

使用 IPv4

如果我们使用'/24',我们的掩码是什么?记住 CIDR 表示法,它就是 255.255.255.0,也就是从最左边的位到第 24 位(包括第 24 位)的 24 位全部被“设置”或“设置为一”。

查找起始地址是通过将地址与你的掩码“AND”运算,即

(192.168.3.5) & (255.255.255.0) = 192.168.3.0 

这是我们的起始地址,或者我们称之为网络地址。

查找结束地址是通过将地址与你的反转掩码(NOT)“OR”运算,即

(192.168.3.5) | ~(255.255.255.0) = 192.168.3.255 

这是我们的结束地址,或者我们称之为广播地址。

使用 IPv6

如果我们使用'/48',我们的掩码是什么?简单来说,它是 ffff:ffff:ffff::,其中从最左边的位到第 48 位(包括第 48 位)的所有 48 位都“设置”或“设置为一”。正如你所见,掩码的求值方式与 IPv4 完全相同。对于我们的 IPv6 子网前缀 '2001:db8:1234::/48',同样的计算方法也适用。还值得记住的是,我们总是使用“十六进制”而不是十进制数字进行寻址,因为 IPv6 完全基于十六进制数字。所以,

查找起始地址是通过将地址与你的掩码“AND”运算,即

(2001:db8:1234::) & (ffff:ffff:ffff::) = 2001:db8:1234::

查找结束地址是通过将地址与你的反转掩码(NOT)“OR”运算,即

(2001:db8:1234::) | ~(ffff:ffff:ffff::) = 2001:db8:1234:ffff:ffff:ffff:ffff:ffff

结果是,对于子网前缀 '2001:db8:1234::/48',我们子网的范围或区间是

IPv6 subnet Start Address> 2001:db8:1234:0:0:0:0:0 (or compressing zeros 2001:db8:1234::) 
IPv6 subnet   End Address> 2001:db8:1234:ffff:ffff:ffff:ffff:ffff

另外请记住,IPv6 中没有广播机制,所以我们没有广播地址。

3. 如何使用 IPv6 子网前缀进行子网划分?

我们知道,我们的第一个前缀长度表示固定位,我们可以从(但不包括)前缀长度值开始,向最右边的位(从左到右)借位。

示例

让我们使用子网前缀 '2001:db8:1234::/48',并借用 2 位进行子网划分。

当进行十六进制到二进制转换时,数字转换的美妙之处就显现出来了。在进行十六进制到二进制或反向转换时,你可以简单直接地将每个十六进制数字转换为二进制形式,而无需关心数字的权重。在十六进制表示法中,每个十六进制数字对应 **4 位**,通常称为“四位组”(nibble)。我们的示例地址展开形式和四位组是

  2    0    0    1  :   0    d    b    8  :   1    2    3    4  :  0    0   ...(the rest zeros)

0010 0000 0000 0001 : 0000 1101 1011 1000 : 0001 0010 0011 0100 : 0000 0000 ...(the rest zeros)

让我们借用 2 位,即第 49 位和第 50 位

0010 0000 0000 0001 : 0000 1101 1011 1000 : 0001 0010 0011 0100 : 0000 ... (其余全部为零)

通过借用 2 位,我们可以得到 22= 4 个唯一的子网,它们是

0010 0000 0000 0001 : 0000 1101 1011 1000 : 0001 0010 0011 0100 : 0000 ...(the rest zeros)
0010 0000 0000 0001 : 0000 1101 1011 1000 : 0001 0010 0011 0100 : 0100 ...(the rest zeros) 
0010 0000 0000 0001 : 0000 1101 1011 1000 : 0001 0010 0011 0100 : 1000 ...(the rest zeros) 
0010 0000 0000 0001 : 0000 1101 1011 1000 : 0001 0010 0011 0100 : 1100 ...(the rest zeros) 

让我们将这些数字转换回十六进制,看看结果

2001:db8:1234:0000::/50 (First subnet)    
2001:db8:1234:4000::/50 (Second subnet)   
2001:db8:1234:8000::/50 (Third subnet)    
2001:db8:1234:c000::/50 (Fourth subnet)   

如果你是一名服务提供商,你可以逐个将这些子网前缀分配给你的客户,前缀长度为'/50',例如,一个客户是 2001:db8:1234:0000::/50,另一个客户是 2001:db8:1234:4000::/50,依此类推。

现在,你的客户应该知道他们分配的地址空间的结束。此时,请记住查找我们子网的起始和结束地址,并执行计算。

首先,你的客户将拥有'/50'的掩码,这意味着 50 位全部“设置”或全部 50 位都是“一”,这给了我们掩码 'ffff:ffff:ffff:c000::'。现在使用这个掩码,我们可以轻松计算起始-结束地址,即我们子网的范围或区间。我们一个接一个地进行。

1st. Customer subnet Start address= 
(2001:db8:1234:0000::) & (ffff:ffff:ffff:c000::) = 2001:db8:1234:0000:0:0:0:0 = 2001:db8:1234::
1st. Customer subnet End address= 
(2001:db8:1234:0000::) |~(ffff:ffff:ffff:c000::) = 2001:db8:1234:3fff:ffff:ffff:ffff:ffff

2nd. Customer subnet Start address= 
(2001:db8:1234:4000::) & (ffff:ffff:ffff:c000::) = 
                  2001:db8:1234:4000:0:0:0:0 = 2001:db8:1234:4000::
2nd. Customer subnet End address= 
(2001:db8:1234:4000::) |~(ffff:ffff:ffff:c000::) = 2001:db8:1234:7fff:ffff:ffff:ffff:ffff

3rd. Customer subnet Start address= 
(2001:db8:1234:8000::) & (ffff:ffff:ffff:c000::) = 
                  2001:db8:1234:8000:0:0:0:0 = 2001:db8:1234:8000::
3rd. Customer subnet End address= 
(2001:db8:1234:8000::) |~(ffff:ffff:ffff:c000::) = 2001:db8:1234:bfff:ffff:ffff:ffff:ffff

4th. Customer subnet Start address= 
(2001:db8:1234:c000::) & (ffff:ffff:ffff:c000::) = 
                  2001:db8:1234:c000:0:0:0:0= 2001:db8:1234:c000::
4th. Customer subnet End address= 
(2001:db8:1234:c000::) |~(ffff:ffff:ffff:c000::) = 2001:db8:1234:ffff:ffff:ffff:ffff:ffff

请注意,每个子网前缀也可以再次用于进行子网划分。例如,第四个客户可以使用子网前缀 '2001:db8:1234:d000::/50' 来再次进行子网划分,通过从 /50 借用位到 /54,当然这取决于他们的需求。

4. 父(或根)前缀的概念

当你向你的服务提供商(或 RIPE、ARIN、APNIC、LACNIC 等)申请 IPv6 前缀范围时,他们会为你分配一个'/xy'前缀长度的前缀。例如,假设 '2001:db8:1234::/48' 已分配给你的网络基础设施。在这种情况下,'2001:db8:1234::/48' 将是你的父(或根)前缀,因为你所有的子分配都必须在你的父前缀下创建。这类似于树数据结构的父(根)节点——同样用于我们的互联网 DNS 系统。

此外,当你创建新的子网前缀时,每个子网前缀也可以称为“父(或根)”。我们可以说这类似于我们在 IPv4 中使用的子网的“网络地址”。但请记住,我们在 IPv6 中没有网络或广播地址机制。

让我们举个例子:假设你拥有前缀 '2001:db8:1234:4000::/50' 并通过借用 2 位(与上面的子网划分示例类似)创建了 4 个新的子前缀,它们是

    p0> 2001:db8:1234:4000::/52
    p1> 2001:db8:1234:5000::/52
    p2> 2001:db8:1234:6000::/52
    p3> 2001:db8:1234:7000::/52 

在这里,我们可以说 '2001:db8:1234:4000::/50' 是上面四个前缀的父级。

 (Parent or root prefix)
2001:db8:1234:4000::/50     (Child prefixes)
                      \__ 2001:db8:1234:4000::/52
                       |_ 2001:db8:1234:5000::/52
                       |_ 2001:db8:1234:6000::/52
                       |_ 2001:db8:1234:7000::/52

请注意,每个子前缀也可能是一个父前缀。当你使用该应用程序时,前缀(第一个轨道条)的值将定义父前缀。如果你使用该应用程序中的数据库,父前缀将作为相等的“前缀”和“父前缀”值自动插入数据库。

摘要

为了找到你子网的起始地址和结束地址,你只需要知道 IPv6 地址和前缀长度值。记住这些位运算(也适用于 IPv4)

(IPv6 Address) &  (/prefix-length mask) is equal to (IPv6 subnet Start address)
(IPv6 Address) | ~(/prefix-length mask) is equal to (IPv6 subnet End address)

(请点击链接查看本文第二部分:IPv6 子网划分 第 2/2 部分[^] )

历史

  • 2013 年 9 月 28 日:v1.0
  • 2014 年 1 月 26 日,v1.1:一些打字更正
  • 2017 年 11 月 13 日,v2.0:Java 应用程序基于 JavaFX
  • 2019 年 10 月 23 日:C# v4.0(基于 .NET 4.7.2)和 JavaFX v3.3
  • 2020 年 1 月 6 日:C# v4.1(基于 .NET 4.8 并提供 IPv4 模式)
  • 2022 年 6 月 9 日:C# v5.0 和 Java v4.0 基于 Java JDK 17(不使用 JavaFX)
© . All rights reserved.