IPv4是数字地址,用点分隔。IPv6是一个字母数字地址,用冒号分隔。


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

# enable eth0
echo 0 > /proc/sys/net/ipv6/conf/eth0/disable_ipv6
一台主机启动后,每一块网卡都会自动生成一个fe80开头的链路本地地址。
设置IPv4会覆盖原来的ip地址,但ipv6设置是新增一个,所以如需保持一个ip地址,则需在新增后删除旧的ip。
可直接通过系统调用ifconfig命令新增或删除IPv6,如:
ifconfig eth0 inet6 add(del) fe80::6a3e:34ff:fe7a:e9be/64
查看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索引
ifr6.ifr6_ifindex = if_nametoindex(“eth0”);
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
tcp/ip规定网络字节序都是大端字节序,但主机字节序可能是大端也可能是小端,因此考虑到与协议的一致以及与同类其它平台产品的互通,发数据包时,将主机字节序转换为网络字节序,收数据包处将网络字节序再转换为主机字节序。
问题:输入不合法时会返回INADDR_NONE(usually -1),而-1是合法的地址(255.255.255.255)。可以使用inet_aton、inet_pton或者getaddrinfo等函数来代替,这些函数提供了一种更清晰的方式来指示错误返回。
注意:inet_ntoa返回值是静态分配的,后面的调用会覆盖上一次的调用。
Inet_aton不支持ipv6,而inet_pton支持,他们参数列表不同,返回值也不同;Inet_pton处理ipv4只支持点分十进制格式,inet_aton支持其他格式。