Ipv6设置与字节序转换

一、Ipv6与Ipv4的区别

IPv4是数字地址,用点分隔。IPv6是一个字母数字地址,用冒号分隔。
在这里插入图片描述

1. IPv4地址

在这里插入图片描述

  • 通常,IPv4地址以点分十进制表示。每个部分代表一组构成8位地址方案的8位地址。

  • IPv4地址组合的数量是有限的。总体而言,可以算出40亿(256^4)个唯一地址。在IPv4地址才开始时,这个数字似乎永远不会过期。但是,现在情况有所不同了。2011年,全球互联网编号分配机构(IANA)分发了IPv4地址空间的最后一块。2015年,IANA正式宣布美国已用完IPv4地址。直到今天,IPv4地址仍然承载着最多(超过90%)的互联网流量。到目前为止,即使目前存在IPv4地址耗尽的问题,也有一些方法可以继续使用IPv4地址。例如,当仅需要一个唯一的IP地址来代表一组设备时,网络地址转换(NAT)是一种方法。除此之外,IP地址可以重复使用。当然,我们已经有了彻底耗尽的解决方案-IPv6地址。

2. IPv6地址

在这里插入图片描述

  • IPv6地址使用以冒号分隔的十六进制数字。它分为八个16位块,构成一个128位地址方案。
  • 对于多个地址块为0的情况,可以用"::“号进行简化,化简原则有这几点:
    1)全0块"0000”,可以简写为"0";
    2)多个全0块,可以简写为"::“;
    3)一个IPv6地址中最多只能出现1个”::“,出现多个全0块时,”::“要简写最长的那一段,如果没有最长的,选距离左边最近的;
    4)”::"可以出现在地址字符串的开头或结尾;

二、Enable IPv6

# enable eth0
echo 0 > /proc/sys/net/ipv6/conf/eth0/disable_ipv6

一台主机启动后,每一块网卡都会自动生成一个fe80开头的链路本地地址。

三、 配置方法

设置IPv4会覆盖原来的ip地址,但ipv6设置是新增一个,所以如需保持一个ip地址,则需在新增后删除旧的ip。

1. ifconfig命令

可直接通过系统调用ifconfig命令新增或删除IPv6,如:

ifconfig eth0 inet6 add(del) fe80::6a3e:34ff:fe7a:e9be/64

2. socket方法

查看ifconfig源码,可发现是通过socket设置ip地址的,可参考其方法直接设置ip。需配置in6_ifreq结构体:

// From linux/ipv6.h
struct in6_ifreq {
   	struct in6_addr ifr6_addr;
   	__u32 ifr6_prefixlen;
   	unsigned int ifr6_ifindex;
};

(1). ifr6_ifindex索引

  • if_nametoindex转换
    指定网络接口名称字符串(如”eth0”)作为参数;若该接口存在,则返回相应的索引,否则返回0。
	ifr6.ifr6_ifindex = if_nametoindex(“eth0”);
  • socket获取索引
	strncpy(ifr.ifr_name, “eth0”, IFNAMSIZ);
	if (ioctl(fd, SIOGIFINDEX, &ifr) < 0) {
		perror("SIOGIFINDEX");
		return;
   	}
   	ifr6.ifr6_ifindex = ifr.ifr_ifindex;

(2). ifr6_addr

	// inet_pton:将IP地址从字符串格式转换成网络地址格式,支持Ipv4和Ipv6。
	inet_pton(AF_INET6, “fe80::6a3e:34ff:fe7a:e9be”, &ifreq6.ifr6_addr);

(3). 新增与删除ip

	ioctl(fd6, SIOCSIFADDR, &ifreq6);	// ADD
	ioctl(fd6, SIOCDIFADDR, &ifreq6);	// DEL

四、 网络字节序和主机字节序

1. 概念

tcp/ip规定网络字节序都是大端字节序,但主机字节序可能是大端也可能是小端,因此考虑到与协议的一致以及与同类其它平台产品的互通,发数据包时,将主机字节序转换为网络字节序,收数据包处将网络字节序再转换为主机字节序。

  • 如地址127.0.0.1 IP是ASCII表示法,把每一部分转化为8位的二进制数:
    01111111.00000000.00000000.00000001 = 2130706433(主机字节序,小端)
  • 将上面的四部分二进制数从右往左按部分重新排列:
    00000001.00000000.00000000.01111111 = 16777343(网络字节序,大端)

2. 转换

(1)主机<=>网络(ipv4)
  • 主机=>网络:htonl (uint32_t)、htons(uint16_t)
    例:htonl(2130706433) => 16777343
  • 网络=>主机:ntohl (uint32_t)、ntohs(uint16_t)
    例:ntohl(16777343) => 2130706433
(2)IP字符串=>字节流(ipv4)
  • 返回网络字节序:inet_addr(“127.0.0.1”) // 16777343
  • 返回主机字节序:inet_network(“127.0.0.1”) // 2130706433

问题:输入不合法时会返回INADDR_NONE(usually -1),而-1是合法的地址(255.255.255.255)。可以使用inet_aton、inet_pton或者getaddrinfo等函数来代替,这些函数提供了一种更清晰的方式来指示错误返回。

(3)IP字符串<=>网络字节流
  • 字符串IP=>网络字节流:inet_aton、inet_pton
  • 网络字节流=>字符串IP:inet_ntoa、inet_ntop

注意:inet_ntoa返回值是静态分配的,后面的调用会覆盖上一次的调用。
Inet_aton不支持ipv6,而inet_pton支持,他们参数列表不同,返回值也不同;Inet_pton处理ipv4只支持点分十进制格式,inet_aton支持其他格式。

  • 1
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值