在Mac OS X上编程查找DNS服务器设置

6
我有一些跨平台的DNS客户端代码,用于执行端到端SMTP操作,在Windows上,我可以通过查找注册表来查找当前DNS服务器IP地址。在Mac上,我可能可以使用SystemConfiguration框架,如第一个答案中所提到的,但是具体的做法并不是立即显而易见的。
例如,SCDynamicStoreCopyDHCPInfo返回一些动态DHCP相关数据,但不包括DNS服务器地址。
5个回答

7

我知道回答这个问题已经很晚了,但可能对其他人有帮助。

以下代码可以帮助完成这个任务...

SCPreferencesRef prefsDNS = SCPreferencesCreate(NULL, CFSTR("DNSSETTING"), NULL);
CFArrayRef services = SCNetworkServiceCopyAll(prefsDNS);
long servicesCount = CFArrayGetCount(services);
for (long i = 0; i < servicesCount; i++) {
    const SCNetworkServiceRef service = (const SCNetworkServiceRef)CFArrayGetValueAtIndex(services, i);
    CFStringRef interfaceServiceID = SCNetworkServiceGetServiceID(service);
    CFStringRef primaryservicepath = CFStringCreateWithFormat(NULL,NULL,CFSTR("State:/Network/Service/%@/DNS"),interfaceServiceID);
    SCDynamicStoreRef dynRef = SCDynamicStoreCreate(kCFAllocatorSystemDefault, CFSTR("DNSSETTING"), NULL, NULL);
    CFPropertyListRef propList = SCDynamicStoreCopyValue(dynRef,primaryservicepath);
    if (propList) {
        CFDictionaryRef dict = (CFDictionaryRef)propList;
        CFArrayRef addresses = (CFArrayRef)CFDictionaryGetValue(dict, CFSTR("ServerAddresses"));
        long addressesCount = CFArrayGetCount(addresses);
        for (long j = 0; j < addressesCount; j++) {
            CFStringRef address = (CFStringRef)CFArrayGetValueAtIndex(addresses, j);
            // Print address
            CFShow(address);
        }
        CFRelease(propList);
    }
    CFRelease(dynRef);
    CFRelease(primaryservicepath);
}
CFRelease(services);
CFRelease(prefsDNS);

6

我知道你需要这个已经有很长时间了,但是没有什么比一个旧的未解决的答案更糟糕的了。由于权限问题,你无法从“/etc/resolv.conf”中访问它们。经过多次搜索和一点运气,我发现你可以通过res_ninit()函数获取它。

// Get native iOS System Resolvers
res_ninit(&_res);
res_state res = &_res;

for (int i = 0; i < res->nscount; i++) {
  sa_family_t family = res->nsaddr_list[i].sin_family;
  int port = ntohs(res->nsaddr_list[i].sin_port);
  if (family == AF_INET) { // IPV4 address
    char str[INET_ADDRSTRLEN]; // String representation of address
    inet_ntop(AF_INET, & (res->nsaddr_list[i].sin_addr.s_addr), str, INET_ADDRSTRLEN);
  } else if (family == AF_INET6) { // IPV6 address
    char str[INET6_ADDRSTRLEN]; // String representation of address
    inet_ntop(AF_INET6, &(res->nsaddr_list [i].sin_addr.s_addr), str, INET6_ADDRSTRLEN);
  }
}
res_ndestroy(res);

2
好的代码。小改进:不要忘记链接libresolv.dylib。 - Maxim Kholyavkin
替代版本,不查看res_state结构内部:https://dev59.com/iozda4cB1Zd3GeqPqLqJ#41303040 - Alnitak

5
你可以使用SystemConfiguration框架,它是用C编写的。
更新:显然,其他网络比我想象的更难使用。搜索关键字“State:/Network/Service/ServiceID/DNS”,其中ServiceID是服务的ID。

1
好的,我最初尝试使用SCDynamicStoreCopyDHCPInfo,这可以获取当前IP地址和子网掩码以及其他一些我不理解的信息,但无法获取DNS服务器。你能否更具体地说明一下? - user33847

1

它们也可以从/etc/resolv.conf中获取


-1
您可以从 /etc/resolv.conf 文件中读取。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接