有时候设备网卡上有多个IPv6,其中只有一个是可用的,另外一个是内网地址,无法使用,如果程序需要绑定一个V6地址的时候,需要获取网卡上的V6地址,并且要求是可用的。

通过ifconfig可用看到,eth0网卡上有2个IP地址,其中只有第一个V6地址的Scope为Global:

eth0      Link encap:Ethernet  HWaddr 52:54:00:1D:79:D1
inet addr:192.168.121.120 Bcast:192.168.121.255 Mask:255.255.255.0
inet6 addr: 2001:250:250:250:250:250:250:222/64 Scope:Global
inet6 addr: fe80::5054:ff:fe1d:79d1/64 Scope:Link
UP BROADCAST RUNNING MULTICAST MTU:1500 Metric:1
RX packets:5999959 errors:0 dropped:0 overruns:0 frame:0
TX packets:104610 errors:0 dropped:0 overruns:0 carrier:0
collisions:0 txqueuelen:1000
RX bytes:317521212 (302.8 MiB) TX bytes:8564391 (8.1 MiB)

那么如何用C获取IPv6地址,并且过滤其中Scope为Global的地址:

#define _GNU_SOURCE    # required for NI_NUMERICHOST
#include <arpa/inet.h>
#include <sys/socket.h>
#include <ifaddrs.h>
#include <stdio.h>
#include <netdb.h> int main ()
{
struct ifaddrs *ifap, *ifa;
struct sockaddr_in6 *sa;
struct sockaddr_in *sa4;
char addr[INET6_ADDRSTRLEN];
char addr4[INET_ADDRSTRLEN]; getifaddrs (&ifap);
for (ifa = ifap; ifa; ifa = ifa->ifa_next) {
if (!ifa->ifa_addr) {
continue;
}
if (ifa->ifa_addr->sa_family==AF_INET6) {
sa = (struct sockaddr_in6 *) ifa->ifa_addr;
getnameinfo(ifa->ifa_addr, sizeof(struct sockaddr_in6), addr,
sizeof(addr), NULL, 0, NI_NUMERICHOST);
printf("Interface: %5s\tAddress: %s, scope: ", ifa->ifa_name, addr); // struct sockaddr_in6 sa;
if (IN6_IS_ADDR_LINKLOCAL(&sa->sin6_addr)) {
printf ("link-local ");
}
if (IN6_IS_ADDR_SITELOCAL(&sa->sin6_addr)) {
printf ("site-local ");
}
if (IN6_IS_ADDR_V4MAPPED(&sa->sin6_addr)) {
printf ("v4mapped ");
}
if (IN6_IS_ADDR_V4COMPAT(&sa->sin6_addr)) {
printf ("v4compat ");
}
if (IN6_IS_ADDR_LOOPBACK(&sa->sin6_addr)) {
printf ("host ");
}
if (IN6_IS_ADDR_UNSPECIFIED(&sa->sin6_addr)) {
printf ("unspecified ");
}
if (IN6_IS_ADDR_MC_GLOBAL(&sa->sin6_addr)){
printf ("global ");
}
printf("\n");
} else if(ifa->ifa_addr->sa_family == AF_INET){
sa4 = (struct sockaddr_in *)ifa->ifa_addr;
getnameinfo(ifa->ifa_addr, sizeof(struct sockaddr_in), addr4,
sizeof(addr4), NULL, 0, NI_NUMERICHOST);
/*inet_ntop(AF_INET, sa4, addr4, INET_ADDRSTRLEN);*/
printf("Interface: %5s\tAddress: %s\n", ifa->ifa_name, addr4);
}
} freeifaddrs(ifap);
return 0;
}

编译下:

gcc -o ipa ipa.c

运行输出:

# ./ipa
Interface: lo Address: 127.0.0.1
Interface: eth0 Address: 192.168.121.120
Interface: eth1 Address: 10.24.0.114
Interface: lo Address: ::1, scope: host
Interface: eth0 Address: 2001:250:250:250:250:250:250:222, scope:
Interface: eth0 Address: fe80::5054:ff:fe1d:79d1%eth0, scope: link-local
Interface: eth1 Address: fe80::5054:ff:fedb:bdd7%eth1, scope: link-local

啊,可见IN6_IS_ADDR_MC_GLOBAL无法判断global的地址,我们只能用排除法了,将IN6_IS_ADDR_MC_GLOBAL判断修改为如下代码:

      // if (IN6_IS_ADDR_MC_GLOBAL(&sa->sin6_addr)){
// printf ("global ");
// }
if (!(IN6_IS_ADDR_LINKLOCAL(&sa->sin6_addr)) && !(IN6_IS_ADDR_SITELOCAL(&sa->sin6_addr)) &&
!(IN6_IS_ADDR_V4MAPPED(&sa->sin6_addr)) && !(IN6_IS_ADDR_LOOPBACK(&sa->sin6_addr)) &&
!(IN6_IS_ADDR_UNSPECIFIED(&sa->sin6_addr))
) {
printf ("global ");
}

重新编译输出:

# ./ipa
Interface: lo Address: 127.0.0.1
Interface: eth0 Address: 192.168.121.120
Interface: eth1 Address: 10.24.0.114
Interface: lo Address: ::1, scope: host
Interface: eth0 Address: 2001:250:250:250:250:250:250:222, scope: global
Interface: eth0 Address: fe80::5054:ff:fe1d:79d1%eth0, scope: link-local
Interface: eth1 Address: fe80::5054:ff:fedb:bdd7%eth1, scope: link-local

Linux C 获取本机IPV4和IPV6地址列表的更多相关文章

  1. Linux中获取本机的最新IPv6地址_更新ddns的脚本

    Linux中获取本机的最新IPv6地址_更新ddns的脚本 转载注明来源: 本文链接 来自osnosn的博客,写于 2019-11-07. 运营商提供ipv6地址. 路由器后有台linux机器,通过e ...

  2. ubuntu(Linux) c++ 获取本机IPv4和ipv6、查询本机IPv4,IPv6

    1.关于 演示环境: Linux xxxxxxx 5.4.0-47-generic #51-Ubuntu SMP Fri Sep 4 19:50:52 UTC 2020 x86_64 x86_64 x ...

  3. linux编程获取本机网络相关参数

    getifaddrs()和struct ifaddrs的使用,获取本机IP 博客分类: Linux C编程   ifaddrs结构体定义如下: struct ifaddrs { struct ifad ...

  4. Linux 获取本机IP、MAC地址用法大全

    getifaddrs()和struct ifaddrs的使用,获取本机IP ifaddrs结构体定义如下: struct ifaddrs { struct ifaddrs *ifa_next; /* ...

  5. Linux下获取本机IP地址的代码

    Linux下获取本机IP地址的代码,返回值即为互联网标准点分格式的字符串. #define ETH_NAME "eth0" //获得本机IP地址 char* GetLocalAdd ...

  6. 获取本机IP、mac地址、计算机名

    python获取本机IP.mac地址.计算机名 在python中获取ip地址和在php中有很大不同,我们先来看一下python 获得本机MAC地址: >>> import uuid ...

  7. js获取本机的网络IP地址

    JavaScript是一门脚本语言,是不能操作文件,读取本地信息的,所以想要获取IP,还需要借助后端技术.方法如下: //获取本机的网络ip地址 function jsonpCallback(res) ...

  8. c#中如何获取本机用户名、MAC地址、IP地址、硬盘ID、CPU序列号、系统名称、物理内存

    我们在利用C#开发桌面程序(Winform)程序的时候, 经常需要获取一些跟系统相关的信息, 以下这些代码获取能有些用处. c#中如何获取本机用户名.MAC地址.IP地址.硬盘ID.CPU序列号.系统 ...

  9. (转)协议森林04 地址耗尽危机 (IPv4与IPv6地址)

    协议森林04 地址耗尽危机 (IPv4与IPv6地址) 作者:Vamei 出处:http://www.cnblogs.com/vamei 欢迎转载,也请保留这段声明.谢谢! IP地址是IP协议的重要组 ...

  10. [Linux]Linux下开启snmp支持IPV4和IPV6

    SNMP简介 简单网络管理协议(SNMP),由一组网络管理的标准组成,包含一个应用层协议(application layer protocol).数据库模型(database schema)和一组资源 ...

随机推荐

  1. 如何在JMeter中配置断言,将非200状态码视为测试成功

    如何在JMeter中配置断言,将非200状态码视为测试成功 引言 在接口测试中,HTTP响应状态码是判断请求是否成功的重要依据.通常情况下,状态码200表示请求成功,而其他状态码则可能表示各种类型的错 ...

  2. Hive - 表相关

    一.文件存储格式 Hive的文件存储格式包括:textfile.sequence.rcfile.orc.parquet textfile (简介)默认的文件格式,基于行存储.建表时不指定存储格式即为t ...

  3. Chrome 133 里程碑式更新 - moveBefore, 或开启前端框架未来新纪元?

    相关背景: Chrome 133 版本(将于 2 月 4 日发布稳定版)引入了一个新的 DOM 操作方法:Node.prototype.moveBefore.这一方法虽然看似简单,但其意义重大,因为它 ...

  4. 基于标签值分布的强化学习推荐算法(Reinforcement Learning Recommendation Algorithm Based on Label Value Distribution)

    前言 看论文的第三天,坚持下去. 慢慢来,比较快. -- 唐迟 本文基于2023年6月28日发表在MATHEMATICS上的一篇名为"基于标签值分布的强化学习推荐算法"(Reinf ...

  5. day1-简介与下载

    为什么创造了golang? 计算机硬件技术更新频繁,不能合理运用多核多CPU的的优势 目前市场缺乏一款简洁高效的编程语言 c++.c运行速度很快,但存在内存泄漏的问题 go语言特点 既做到了静态语言的 ...

  6. MyCat分库分表-练习

    模拟这样一个场景: 1.将数据库按业务"垂直"拆分成用户库和订单库: 2.用户库做主从,读写分离: 3.订单库做"水平"切分,并且每个分片表做主从,读写分离: ...

  7. Swagger OpenAPI Schema 为空时 Example Value 显示 "string" 的原因及解决方案

    解决Swagger UI示例值显示"string"的问题 最近在使用ObjectScript生成JSON接口文档时,遇到了一个奇怪的问题: 生成的JSON数据是正常的. 但Swag ...

  8. 【多进程并发笔记】Python-Multiprocess

    目录 调用函数后,函数内的变量如何释放? python2.7怎么使用多线程加速for loop 多进程进程池,函数序列化错误的处理 Time模块计算程序运行时间 使用多进程,Start()后,如何获得 ...

  9. 一款基于.NET开源、强大的网络管理和网络问题排查工具!

    前言 今天大姚给大家分享一款基于.NET开源.免费.功能强大的网络管理和网络问题排查工具:NETworkManager. 项目介绍 NETworkManager 是一个基于.NET开源(GPL-3.0 ...

  10. mysql 表的创建,修改,删除

    查看数据库所有表 show tables 创建 create table 表名 ( 列名 类型 约束条件 ... ) 类型有整形: tinyint(1B) ,smallint(2B),mediumin ...