IPv6 scope id

在查看<netinet/in.h>中sockaddr_in6代码时,发现有一个成员sin6_scope_id,表示IPv6 scope-id。而在sockaddr_in中是没有该成员的。
那么,这个成员是干什么的呢?
要讨论这个问题,先看一下IPv6的基础知识:IPv6地址分类及表示法。
 
IPv6地址分类及表示方法
 
  • 一个IPv6地址字符表示
ABCD:EF01:2345:6789:ABCD:EF01:2345:6789
一共128bit,上面用16进制字符串表示,地址划分为8个块,每个块16bit,块与块之间用“:”隔开。
 
  • 带有子网前缀的IPv6地址表示
ABCD:EF01:2345:6789:ABCD:EF01:2345:6789/64
这里/64表示前64bit都是子网络号
 
  • 带有端口号的IPv6地址表示
[ABCD:EF01:2345:6789:ABCD:EF01:2345:6789]:8080
 
  • 化简
对于多个地址块为0的情况,可以用"::"号进行简化
化简原则有这几点:
1)全0块"0000",可以简写为"0";
2)多个全0块,可以简写为"::";
3)一个IPv6地址中最多只能出现1个"::",出现多个全0块时,"::"要简写最长的那一段,如果没有最长的,选距离左边最近的;
4)"::"可以出现在地址字符串的开头或结尾;
 
具体示例:
化简前
化简后
备注
ABCD:0000:2345:0000:ABCD:0000:2345:0000
ABCD:0:2345:0:ABCD:0:2345:0
全0块"0000",简写为"0"
ABCD:EF01:0:0:0:0:0:6789
ABCD:EF01::6789
多个全0块,简写为"::"
ABCD:0:0:0:ABCD:0:0:6789
ABCD::ABCD:0:0:6789
多个可以简写的全0块,但只能简写最长的那个或者左边那个(如果同时2个最长)
0:0:0:0:0:0:0:1
::1
开头多个全0块
2001:0:0:0:0:0:0:0
2001::
末尾多个全0块
 
IPv6地址类型
 
IPv6整体上分三类:单播地址,任播地址,组播地址。
 
  • 单播地址:一个单播地址对应一个接口,发往单播地址的数据包会被对应的接口接收;
  • 任播地址:一个任播地址对应一组接口,发往任播地址的数据包会被这组接口的其中一个接收,被哪个接口接收由具体的路由协议确定;
  • 组播地址:一个组播地址对应一组接口,发往组播地址的数据包会被这组的所有接口接收;
 
特殊地址
具体地址分配如下,任播存在于单播地址之中,没有专门的区分:
 
地址类型
二进制前缀
IPv6表示
未指定
00...0(全0)
::/128
环回地址
00...1(最后1位是1)
::1/128
组播地址
11111111
FF00::/8
本地链路单播地址
1111111010
FE80::/10
全球单播地址
剩余的所有
 
  • 未指定地址:主要用于系统启动之初,尚未分配IP时,对外请求IP地址时,作为源地址使用,它不能用于数据包的目的地址之中。
  • 环回地址:用于自己向自己发送数据包时使用,在日常网络排错中可用测试网络层协议状态。
  • 本地链路单播地址(Link-Local addressing):前缀FE80::/10,作用是在没有路由(网关)存在的网络中,主机通过MAC地址自动配置生成IPv6地址,仅能在本地网络中使用。::FE80::/10 这些链路本地地址指明,这些地址只在区域连线中合法,有的类似于IPv4中的169.254.0.0/16。
 
IPv6地址空间由IANA组织分配,官网:https://www.iana.org/
 
IPv6 Scope ID
回到IPv6 scope的问题。
 
全世界的IPv6本地链路地址(Link-Local addressing)都有相同网络(FE80::/10),那么如何区分特定网络呢?
这就需要用到Scope ID(作用域ID),也称为Zone ID(区域ID),以免与多播scope flags混淆。Scope ID仅用于本地链接,使用百分号追加在地址后面。其内容特定于操作系统,例如Windows使用数字fe80::2%3,Linux使用网卡名fe80::2%eth0。在URI中使用时,百分号需要编码,如fe80::2%eth1 应显示为http://[fe80::a%25en1]。
 
PS:只有位于同一Scope ID下的两端,并且物理上直联,才能使用IPv6进行网络通信。
 
参考
 
posted @ 2022-02-15 23:38  明明1109  阅读(2716)  评论(0编辑  收藏  举报