从 IPv4 到 IPv6 最明显的变化就是网址的长度不同了,IPv6 地址长度为128比特而 IPv4 地址长度为32比特。所有 IPv6 地址的个数可达3.4x1038个。
1.1 IPv6 地址格式
IPv6 地址在许多情况下都由两个逻辑部分组成:64位的网络前缀部分和64位的主机寻址部分,而后者通常都是主机依照 MAC 接口地址自动生成的。IPv6 地址由8组长度为16比特的十六进制数值组成,各组之间由
冒号(:)分隔开,示例如下 :
aaaa : aaaa : aaaa : aaaa : aaaa : aaaa : aaaa : aaaa
其中每一个aaaa, 一组长度为16比特的十六进制数,而 a 是一位长度为4比特的十六进制数值,以下就是个IPV6的实例.
3ffe:ffff:100:f101:210:a4ff:fee3:9566
1.2 ipv6 地址变形:
因为IPV6地址位数太多.因此如果出现全零的段(0000),可以省写为 0,这个跟IPV4一样.
如果出现连续的全0段,还可以直接写成::,如1080:0:0:0:8:810:213C:123A地址可以省写为
1080::8:810:213C:123A,但这种写法在一个地址里只能出现一次.比如本地回环地址: 它的简写就是::1 等同于ipv4的 127.0.0.1
还有一种表达法也是常用. 可以用“IPv6地址/前缀长度”来表示地址前缀. 前缀长度是一个十进制值,指定该地址中最左边的用于组成前缀的位数. 址前缀在一定意义上代表了这个IP地址的类型.
例如: 假如一个IP地址它的地址前缀为16位,IP地址为“1080::8:810:213C:123A”,则用地址前缀法表示就为:1080::8:810:213C:123A/32
后四个 8 位可使用十进制来表示 IPv4 地址。 例如,一个与 IPv6 相一致的 IPv4 地址为 : 0:0:0:0:0:0.192.168.0.1 。
决定这些IP地址类型的“地址前缀”(Format Prefix ,FP)。顾名思义,地址前缀就是在地址的最前面那段数字。当然也属于128位地址空间范围之中,通过不同的地址前缀来代表不同的地址类型。类似于IPV4的子网掩码.
前缀数的换算,/32对应的地址数量为2的(128-32)次方=2的96次方个,/48对应的地址数量为2的(128-48)次方=2的80次方个,/128对应的地址数量为2的(128-128)次方=1个地址。 2的32次方对应的地址数量约为40亿个。
1.3 所有IPV6地址变形总结
(a): 前头的零可以去掉。
(b):0000 = 0 (压缩排列)。
(c): “ :: ”代表一组或多组 16 位零,并且在一个地址中仅能出现一次。 例如: 2001:0:13FF:09FF:0:0:0:0001 = 2001:0:13FF:09FF::1
(d): 后四个 8 位可使用十进制来表示 IPv4 地址。 例如,一个与 IPv6 相一致的 IPv4 地址为 : 0:0:0:0:0:0.192.168.0.1 。
2.Ipv6网络的使用
Linux 对IPV6的支持已经非常完善了,在我的RHEL机器上.
ifconfig 会显示IPV6地址.
ifconfig eth0 Link encap:Ethernet HWaddr 00:0C:29:51:C6:5F inet addr:192.168.2.151 Bcast:192.168.2.255 Mask:255.255.255.0 inet6 addr: fe80::20c:29ff:fe51:c65f/64 Scope:Link UP BROADCAST RUNNING MULTICAST MTU:1500 Metric:1 RX packets:156802 errors:0 dropped:0 overruns:0 frame:0 TX packets:121246 errors:0 dropped:0 overruns:0 carrier:0 collisions:0 txqueuelen:1000 RX bytes:146606620 (139.8 MiB) TX bytes:79355802 (75.6 MiB) Interrupt:169 Base address:0x2000 lo Link encap:Local Loopback inet addr:127.0.0.1 Mask:255.0.0.0 inet6 addr: ::1/128 Scope:Host UP LOOPBACK RUNNING MTU:16436 Metric:1 RX packets:7675 errors:0 dropped:0 overruns:0 frame:0 TX packets:7675 errors:0 dropped:0 overruns:0 carrier:0 collisions:0 txqueuelen:0 RX bytes:4329827 (4.1 MiB) TX bytes:4329827 (4.1 MiB) |
Ipv6网络不能使用ping 来测试网络,而是采用ping6 来处
理,注意地址不能带地址前缀(/32之类)
[root@rhel5 ~]# ping6 ::1
PING ::1(::1) 56 data bytes
64 bytes from ::1: icmp_seq=0 ttl=64 time=2.93 ms
64 bytes from ::1: icmp_seq=1 ttl=64 time=0.176 ms
64 bytes from ::1: icmp_seq=2 ttl=64 time=0.057 ms
64 bytes from ::1: icmp_seq=3 ttl=64 time=0.038 ms
64 bytes from ::1: icmp_seq=4 ttl=64 time=0.052 ms
--- ::1 ping statistics ---
5 packets transmitted, 5 received, 0% packet loss, time 4003ms
rtt min/avg/max/mdev = 0.038/0.651/2.934/1.142 ms, pipe 2 |
用ping6 来拼其它机器,因为一般LINUX不带IPV6路由,因此必须用-I 指过从哪一个块网卡发出IPV6包
ping6 fe80::225:86ff:fe92:49b8 -I eth0 PING fe80::225:86ff:fe92:49b8(fe80::225:86ff:fe92:49b8) from fe80::21d:fff:fe28:97c8 eth0: 56 data bytes 64 bytes from fe80::225:86ff:fe92:49b8: icmp_seq=0 ttl=64 time=1.95 ms 64 bytes from fe80::225:86ff:fe92:49b8: icmp_seq=1 ttl=64 time=0.162 ms 64 bytes from fe80::225:86ff:fe92:49b8: icmp_seq=2 ttl=64 time=0.162 ms 64 bytes from fe80::225:86ff:fe92:49b8: icmp_seq=3 ttl=64 time=0.166 ms 64 bytes from fe80::225:86ff:fe92:49b8: icmp_seq=4 ttl=64 time=0.164 ms 64 bytes from fe80::225:86ff:fe92:49b8: icmp_seq=5 ttl=64 time=0.159 ms 64 bytes from fe80::225:86ff:fe92:49b8: icmp_seq=6 ttl=64 time=0.166 ms
--- fe80::225:86ff:fe92:49b8 ping statistics --- 7 packets transmitted, 7 received, 0% packet loss, time 6011ms rtt min/avg/max/mdev = 0.159/0.418/1.953/0.626 ms, pipe 2 |
3.IPV6 包结构
IPv4与IPv6包头结构比较
IPv4中所有包头以32个字节为单位,即基本的长度单位是4个字节。表1为IPv4的包头格式。
IPv6中,包头以64个字节为单位,且包头的总长度是40个字节。IPv6的包头格式如表2所示。
比较两种包头格式可知,IPv6对IPv4进行了较大改进:
首先,取消了IPv4包头的6个字段:IP包头长度(Header Length)、服务类型(Service Type)、标识(Identification)、标志(Flag)、标志偏移量(Fragment Offset)及头标校验和(Header Checksum);
其次,在IPv6中有三个控制字段重新命名,并在一些条件下重新定义:长度(Length)、服务类型(Service Type)、生存时间(Time to Live);
最后,增加了两个新的字段:优先级(Priority)和流标识(Flow Label)。
以下是实际抓包通讯
4.IPV6 Socket 编程
IPV6除了地址处理和创建socket之外,其余编程都跟IPV4 类似.
4.1 创建IPV6 Socket ,domain采用 PF_INET6.
socket(PF_INET6,SOCK_STREAM,0);
4.2 IPV6 Socket 地址表示.使用struct sockaddr_in6 .注意它的尺寸大于 struct sockaddr addr,地址族使用AF_INET6
struct in6_addr {
uint8_t s6_addr[16]; /* 128 bit 字节地址 */
}; #define SIN6_LEN /* required for compile-time tests */
struct sockaddr_in6 { uint8_t sin6_len; /* = SIN6_LEN */ sa_family_t sin6_family; /* = AF_INET6 */ in_port_t sin6_port; /* */ uint32_t sin6_flowinfo; /* priority and flow label */ struct in6_addr sin6_addr; /* IPV6 的任意地址是 in6addr_any */ };
|