如何知道使用IPv6的C中接口的IP地址
假设我想按接口名列出Linux机器上的所有IP地址,使用和 我能找到的最好的建议是使用支持IPv6的,类似于来自的帖子。 但是,getifaddrs使用struct ifaddrs,它使用与IPv6不兼容的struct sockaddr。相反,它也应该是指向具有struct in6_addr的联合的指针如何知道使用IPv6的C中接口的IP地址,c,linux,interface,ipv6,ipv4,C,Linux,Interface,Ipv6,Ipv4,假设我想按接口名列出Linux机器上的所有IP地址,使用和 我能找到的最好的建议是使用支持IPv6的,类似于来自的帖子。 但是,getifaddrs使用struct ifaddrs,它使用与IPv6不兼容的struct sockaddr。相反,它也应该是指向具有struct in6_addr的联合的指针 这是怎么处理的?GetIFADRS如何支持IPv6?文档是否过时了?我的C已经严重生锈了,并且包含诸如struct sockaddr_in6之类的联合的成员的结构不再适合我的大脑,因此在我采用
这是怎么处理的?GetIFADRS如何支持IPv6?文档是否过时了?我的C已经严重生锈了,并且包含诸如struct sockaddr_in6之类的联合的成员的结构不再适合我的大脑,因此在我采用的最佳剪切粘贴传统中,它列举了系统的IPv4地址,而使用getnameinfo,借助GetIFADRS手册页的一些帮助,其中有一个更好的示例:
#define _GNU_SOURCE # required for NI_NUMERICHOST
#include <arpa/inet.h>
#include <sys/socket.h>
#include <ifaddrs.h>
#include <stdio.h>
#include <stdlib.h>
#include <netdb.h>
int main ()
{
struct ifaddrs *ifap, *ifa;
struct sockaddr_in6 *sa;
char addr[INET6_ADDRSTRLEN];
if (getifaddrs(&ifap) == -1) {
perror("getifaddrs");
exit(1);
}
for (ifa = ifap; ifa; ifa = ifa->ifa_next) {
if (ifa->ifa_addr && 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: %s\tAddress: %s\n", ifa->ifa_name, addr);
}
}
freeifaddrs(ifap);
return 0;
}
记住在每件事中都添加错误检查;本例中省略了一些错误检查。是什么让您认为sockaddr与IPv6不兼容?你把它和sockaddr_混淆了吗?那些确实令人混淆。我发现“sockaddr”非常依赖于平台,而且通常ipv6需要不同的结构。不,sockaddr与平台无关。IPv6确实需要与IPv4 sockaddr_不同的结构,而不是6中的sockaddr_。但两者都与sockaddr兼容。sockaddr应用作指针,而sockaddr_存储应用于存储和转换,或与sockaddr_in和sockaddr_in 6结合。此程序在我的机器上出现分段错误。经过一些调查,根据getifaddrs上的人的说法,ifa_addr可能包含一个空指针。将此检查添加到if语句:if ifa->ifa\u addr&&ifa->ifa\u addr->sa\u family==AF_INET6@KimNyholm这个简单的例子省略了错误检查。在严肃的代码中,您还将检查GetIFADRS的返回值,以确保它返回了有效的数据。保存在my~/Projects文件夹中的文件nif-IPv6-Adrs-List.c中,在macOS10.15.x/Catalina上编译为:gcc-Wall-o~/Projects/nif-IPv6-Adrs-List~/Projects/nif-IPv6-Adrs-List.c。所示代码截至2020年9月8日,已编译良好&~/Projects/nif-IPv6-Adrs-List可以运行良好,无任何错误。@atErik这是个好消息。我甚至没有考虑可移植性。
Interface: lo Address: ::1
Interface: br0 Address: fdbf:e684:d5fb:6:6e62:6dff:fed1:dfad
Interface: br0 Address: 2001:db8:1f80:81c6:6e62:6dff:fed1:dfad
Interface: br0 Address: fe80::6e62:6dff:fed1:dfad%br0
Interface: virbr1 Address: fe80::5054:ff:fece:bfec%virbr1
Interface: virbr0 Address: fe80::5054:ff:fef9:c92e%virbr0
Interface: virbr2 Address: fe80::5054:ff:fedd:ea18%virbr2
Interface: vnet0 Address: fe80::fc54:ff:fe90:de19%vnet0
Interface: vnet1 Address: fe80::fc54:ff:fede:b69c%vnet1