【问题标题】:Definitive guide to understanding how to formulate an IPv6 address了解如何制定 IPv6 地址的权威指南
【发布时间】:2011-06-21 01:54:23
【问题描述】:

为了好玩,我想更好地了解 IPv6 地址中的构建块或元素。

根据我的理解,以下是基础知识:

  • IPv6 地址长度为 128 位(写成 8 个块,每个块有 16 位)
  • 每个块都被编码为 0 到 0xffff 之间的十六进制数字。前导零可以省略。
  • 可以附加一个 IPv4 点四进制地址,它将占用 IPv6 地址的低 32 位。 1:2:3:4:5:6:200.201.202.203。 (IPv4 的规则符合预期。)
  • IPv4 表示只能出现在末尾。
  • 可以使用双冒号语法来表示一个或多个带有零的块。 1:2::7:8 相当于 1:2:0:0:0:0:7:8。
  • 每个 IPv6 地址只能有一个双冒号,否则语法错误。
  • 双冒号可能出现在 ip6 的开头、中间或结尾,但不能出现在 IPv4 点分四组地址中。

以上几点都正确吗?

请不要告诉我阅读 RFC。关于这个问题有好几个,实际上都没有一个简单的例子来描述各种编码机制。我相信很多人会喜欢一个带有示例的简单列表。

在线测试工具 最接近的在线帮助工具是 http://www.dominicsayers.com/source/beta/is_email/test/ 但是这些信息令人困惑,它实际上并没有用简单的英语说明什么是对和错以及为什么。它实际上也是为当然可能包含 IPv6 地址的电子邮件而构建的,因此它并不完全理想。

【问题讨论】:

  • 很遗憾,指向 is_email/test 程序的 dominicsayers 链接已损坏。
  • 在 IPv4 地址中,您可以省略中间的零四边形。例如,10.0.0.248 可以写成 10.248。我不确定你是否可以在 IPv6 地址的尾部这样做,比如 1:2:3:4:5:6:10.248。
  • 双冒号只能使用一次。如果任何其他块是 :0000: 您可以将每个块缩短为 :0:.

标签: ipv6


【解决方案1】:

带有区域 ID 的 IPv6 地址具有唯一的表示法,尽管它并不特定于地址本身。在具有多个启用 IPv6 的接口的系统中,必须以某种方式消除链路本地地址的歧义。它使用“%”符号完成。

FE80::AA%eth0 指通过 eth0 接口可达的链路本地地址。 在某些平台可以是接口索引,FE80::AA%10

【讨论】:

    【解决方案2】:

    总的来说,是的,你的观点是正确的。

    您确定您阅读了 RFC 吗? RFC 3513, section 2.2 正是您所要求的。对于 RFC,它写得很好。 =) 我不得不指出这一点,因为它可能对未来阅读这个问题的人非常有帮助。

    【讨论】:

    • 我希望我阅读了正确的 RFC,因为其中有一些是相关的。 2.2 确实包含了一些示例,但它不包含任何容易犯错误的示例...例如,它不包含带有两个空 :: 块的 ip6 并说明为什么这是错误的...
    • @mP,嗯,它确实说The "::" can only appear once in an address.,但你是对的,它没有说明原因。如果你仔细想想,不难找出原因。想象像::1:: 这样的地址,它可以扩展为 6 个唯一地址。允许两个是模棱两可的,如果它不会模棱两可,那就没用了。
    • RFC 5952, A Recommendation for IPv6 Address Text Representation 更新了 IPv6 地址的规范文本表示标准。
    【解决方案3】:

    这一段显然是错别字:

    可以使用双冒号语法来表示一个或多个带有零的块。 1:2::6:7 等价于 1:2:3:4:5:6:7:8。

    1:2::6:7 表示1:2:0:0:0:0:6:7

    我以前没听说过:

    双冒号可能[不会出现]在 ip4 点地址中。

    但是我做了一个测试程序,似乎可以确认。

    $ ./testipv6 0:0:0:0:0:0:192.168.0.1
    0:0:0:0:0:0:192.168.0.1: OK
    
    $ ./testipv6 0:0:0:0:0:0:192.168::1
    0:0:0:0:0:0:192.168::1: ERROR
    

    否则我认为你说的一切都可以。


    testipv6.c

    #include <stdio.h>
    #include <stdlib.h>
    #include <arpa/inet.h>
    #include <netinet/in.h>
    
    int convert(const char *addr)
    {
        struct in6_addr dst;
    
        return inet_pton(AF_INET6, addr, (void *)&dst);
    }
    
    int main(int argc, char **argv)
    {
        if (argc == 1) {
            fprintf(stderr, "Usage: testipv6 <addr>\n");
            exit(2);
        }
    
        while (argc > 1) {
            argc--, argv++;
            const char *addr = argv[0];
    
            if (convert(addr)) {
                printf("%s: OK\n", addr);
            } else {
                printf("%s: ERROR\n", addr);
            }
        }
    }
    

    【讨论】:

    • 感谢您发现错字。我自己也不确定,因为有很多例外。看看电子邮件可能出现的废话 - 可以将 cmets 嵌入其中。这可能已经过时,但为什么包含它却超出了我的范围。我尝试编写一个程序,但这种黑盒测试可能会遗漏一些我不知道的奇怪情况:)
    • 我只给mike打分是因为他在官方的rfc中找到了一个sn-p。
    • 源代码+1。有时,学习某些东西的最好方法就是亲自体验它。 =) 另外,这是对 inet_pton() 的一个很好的介绍,任何为 IPv6 编写 C 的人都需要了解它。
    猜你喜欢
    • 1970-01-01
    • 2010-11-13
    • 2010-10-08
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-12-25
    • 2016-02-06
    相关资源
    最近更新 更多