如何使用libresolv编程读取/etc/resolv.conf中的IPv4与IPv6域名服务器?
使用libresolv读取/etc/resolv.conf中的DNS服务器信息
Hey there! 我最近在尝试用libresolv库读取/etc/resolv.conf里的IPv4和IPv6域名服务器信息,先给大家看看我的/etc/resolv.conf内容:
Dynamic resolv.conf(5) file for glibc resolver(3) generated by resolvconf(8)DO NOT EDIT THIS FILE BY HAND -- YOUR CHANGES WILL BE OVERWRITTEN127.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 <s...
后来我把它补全成了完整可运行的程序,能正确解析出两种类型的DNS服务器地址:
#include <resolv.h> #include <stdio.h> #include <arpa/inet.h> #include <string.h> int main() { // 初始化解析器,自动读取/etc/resolv.conf if (res_init() != 0) { perror("Failed to initialize resolver"); return 1; } printf("Found %d DNS servers:\n", _res.nscount); // 遍历所有配置的DNS服务器 for (int i = 0; i < _res.nscount; i++) { char addr_buffer[INET6_ADDRSTRLEN]; memset(addr_buffer, 0, sizeof(addr_buffer)); switch (_res.nsaddr_list[i].sa.sa_family) { case AF_INET: { struct sockaddr_in *ipv4 = (struct sockaddr_in *)&_res.nsaddr_list[i].sa; inet_ntop(AF_INET, &ipv4->sin_addr, addr_buffer, INET_ADDRSTRLEN); printf(" IPv4 Server %d: %s\n", i+1, addr_buffer); break; } case AF_INET6: { struct sockaddr_in6 *ipv6 = (struct sockaddr_in6 *)&_res.nsaddr_list[i].sa; inet_ntop(AF_INET6, &ipv6->sin6_addr, addr_buffer, INET6_ADDRSTRLEN); printf(" IPv6 Server %d: %s\n", i+1, addr_buffer); break; } default: printf(" Server %d: Unknown address family (%d)\n", i+1, _res.nsaddr_list[i].sa.sa_family); break; } } return 0; }
几个关键点要注意:
res_init()是核心函数,它会自动加载/etc/resolv.conf的内容,填充全局的_res结构体。_res.nscount记录了配置文件里的DNS服务器总数,_res.nsaddr_list数组里存储了每个服务器的套接字地址信息。- 用
sa_family判断地址类型:AF_INET对应IPv4,AF_INET6对应IPv6,再用inet_ntop()把二进制地址转换成人类可读的字符串。 - 编译的时候必须链接resolv库,用这个命令:
gcc dns_reader.c -o dns_reader -lresolv
运行这个程序后,就能得到和配置文件对应的输出啦:
Found 2 DNS servers: IPv4 Server 1: 127.0.0.53 IPv6 Server 2: 2001:4860:4860::8888
内容的提问来源于stack exchange,提问作者drautb
相关产品推荐
相关产品推荐

