以编程方式检索 IPv4 和 IPv6 名称服务器

Retrieve IPv4 and IPv6 nameservers programmatically

我正在尝试使用 libresolv 读取我的 /etc/resolv.conf 文件中的 IPv4 和 IPv6 名称服务器:

# Dynamic resolv.conf(5) file for glibc resolver(3) generated by resolvconf(8)
#     DO NOT EDIT THIS FILE BY HAND -- YOUR CHANGES WILL BE OVERWRITTEN
# 127.0.0.53 is the systemd-resolved stub resolver.
# run "systemd-resolve --status" to see details about the actual nameservers.

nameserver 127.0.0.53
nameserver 2001:4860:4860:0:0:0:0:8888

这是我的 C 程序:

#include <resolv.h>
#include <stdlib.h>

int main(int argc, char** argv)
{
    res_state res = malloc(sizeof(struct __res_state));
    res_ninit(res);

    printf("IPv4 nscount:  %d\n", res->nscount);
    printf("IPv6 nscount6: %d\n", res->_u._ext.nscount6);

    return 0;
}

产生此输出:

IPv4 nscount:  2
IPv6 nscount6: 0

这让我很吃惊。为什么它把 IPv6 地址算作 IPv4 地址?

GDB显示第二个地址被归零:

(gdb) display res.nsaddr_list[0]
5: res.nsaddr_list[0] = {sin_family = 2, sin_port = 13568, sin_addr = {s_addr = 889192575}, sin_zero = "[=13=]0[=13=]0[=13=]0[=13=]0[=13=]0[=13=]0[=13=]0"}
(gdb) display res.nsaddr_list[1]
6: res.nsaddr_list[1] = {sin_family = 0, sin_port = 0, sin_addr = {s_addr = 0}, sin_zero = "[=13=]0[=13=]0[=13=]0[=13=]0[=13=]0[=13=]0[=13=]0"}

谁能帮我理解这种行为?

您真的不应该访问解析器状态的 _u._ext 部分,它们是内部实现细节。 nscount6 成员当前未使用且始终为零。必须保留它以避免由于 struct offset/size 更改而更改 ABI。

如果您需要名称服务器列表,您应该自己解析 /etc/resolv.conf。请注意,glibc 最终还将支持三个以上的名称服务器,这些额外的解析器将不会反映在 public 解析器状态中。