给定 BSD 名称或对网络接口的引用,如何获取其网关和 DNS 服务器?
Given the BSD name or a reference to a network interface, how to get its gateway and DNS servers?
在 macOS 应用程序中,我正在尝试获取网络接口的网关/路由器和 DNS 服务器。该接口可以通过其 BSD 名称或使用带 SCNetworkInterfaceRef
或 SCNetworkServiceRef
的系统配置来标识。 (以合适者为准。)
具体来说,如果用户打开“网络”系统首选项和 select 此连接,我想要获得将显示给用户的相同信息。 (请注意,它的网关在网络系统首选项中称为“路由器”,出于这个问题的目的,我交替使用这两个术语。)
此应用程序是用 Objective-C 编写的,但 Swift 解决方案也很好,因为通常可以直接将其移植到 Objective-C。
我已经想出了如何做到这一点,给出 SCNetworkServiceRef
。这两个函数将 return 指定网络的网关和 DNS 服务器:
CFStringRef copyNetworkServiceGateway(SCNetworkServiceRef service)
{
CFStringRef result = NULL;
CFStringRef interfaceServiceID = SCNetworkServiceGetServiceID(service);
CFStringRef servicePath = CFStringCreateWithFormat(NULL, NULL, CFSTR("State:/Network/Service/%@/IPv4"),
interfaceServiceID);
SCDynamicStoreRef dynamicStoreRef = SCDynamicStoreCreate(kCFAllocatorSystemDefault,
CFSTR("your.app.name.here"), NULL, NULL);
CFDictionaryRef propList = (CFDictionaryRef)SCDynamicStoreCopyValue(dynamicStoreRef, servicePath);
if (propList) {
result = (CFStringRef)CFDictionaryGetValue(propList, CFSTR("Router"));
CFRetain(result);
CFRelease(propList);
}
CFRelease(servicePath);
CFRelease(dynamicStoreRef);
return result;
}
CFArrayRef copyNetworkServiceDNSServers(SCNetworkServiceRef service)
{
CFArrayRef result = NULL;
CFStringRef interfaceServiceID = SCNetworkServiceGetServiceID(service);
// If the user has added custom DNS servers, then we have to use this path to find them:
CFStringRef servicePath = CFStringCreateWithFormat(NULL, NULL, CFSTR("Setup:/Network/Service/%@/DNS"),
interfaceServiceID);
SCDynamicStoreRef dynamicStoreRef = SCDynamicStoreCreate(kCFAllocatorSystemDefault,
CFSTR("your.app.name.here"), NULL, NULL);
CFDictionaryRef propList = (CFDictionaryRef)SCDynamicStoreCopyValue(dynamicStoreRef, servicePath);
CFRelease(servicePath);
if (!propList) {
// In this case, the user has not added custom DNS servers and we use this path to
// get the default DNS servers:
servicePath = CFStringCreateWithFormat(NULL, NULL, CFSTR("State:/Network/Service/%@/DNS"),
interfaceServiceID);
propList = (CFDictionaryRef)SCDynamicStoreCopyValue(dynamicStoreRef, servicePath);
CFRelease(servicePath);
}
if (propList) {
result = (CFArrayRef)CFDictionaryGetValue(propList, CFSTR("ServerAddresses"));
if (result) {
CFRetain(result);
}
CFRelease(propList);
}
CFRelease(dynamicStoreRef);
return result;
}
在 macOS 应用程序中,我正在尝试获取网络接口的网关/路由器和 DNS 服务器。该接口可以通过其 BSD 名称或使用带 SCNetworkInterfaceRef
或 SCNetworkServiceRef
的系统配置来标识。 (以合适者为准。)
具体来说,如果用户打开“网络”系统首选项和 select 此连接,我想要获得将显示给用户的相同信息。 (请注意,它的网关在网络系统首选项中称为“路由器”,出于这个问题的目的,我交替使用这两个术语。)
此应用程序是用 Objective-C 编写的,但 Swift 解决方案也很好,因为通常可以直接将其移植到 Objective-C。
我已经想出了如何做到这一点,给出 SCNetworkServiceRef
。这两个函数将 return 指定网络的网关和 DNS 服务器:
CFStringRef copyNetworkServiceGateway(SCNetworkServiceRef service)
{
CFStringRef result = NULL;
CFStringRef interfaceServiceID = SCNetworkServiceGetServiceID(service);
CFStringRef servicePath = CFStringCreateWithFormat(NULL, NULL, CFSTR("State:/Network/Service/%@/IPv4"),
interfaceServiceID);
SCDynamicStoreRef dynamicStoreRef = SCDynamicStoreCreate(kCFAllocatorSystemDefault,
CFSTR("your.app.name.here"), NULL, NULL);
CFDictionaryRef propList = (CFDictionaryRef)SCDynamicStoreCopyValue(dynamicStoreRef, servicePath);
if (propList) {
result = (CFStringRef)CFDictionaryGetValue(propList, CFSTR("Router"));
CFRetain(result);
CFRelease(propList);
}
CFRelease(servicePath);
CFRelease(dynamicStoreRef);
return result;
}
CFArrayRef copyNetworkServiceDNSServers(SCNetworkServiceRef service)
{
CFArrayRef result = NULL;
CFStringRef interfaceServiceID = SCNetworkServiceGetServiceID(service);
// If the user has added custom DNS servers, then we have to use this path to find them:
CFStringRef servicePath = CFStringCreateWithFormat(NULL, NULL, CFSTR("Setup:/Network/Service/%@/DNS"),
interfaceServiceID);
SCDynamicStoreRef dynamicStoreRef = SCDynamicStoreCreate(kCFAllocatorSystemDefault,
CFSTR("your.app.name.here"), NULL, NULL);
CFDictionaryRef propList = (CFDictionaryRef)SCDynamicStoreCopyValue(dynamicStoreRef, servicePath);
CFRelease(servicePath);
if (!propList) {
// In this case, the user has not added custom DNS servers and we use this path to
// get the default DNS servers:
servicePath = CFStringCreateWithFormat(NULL, NULL, CFSTR("State:/Network/Service/%@/DNS"),
interfaceServiceID);
propList = (CFDictionaryRef)SCDynamicStoreCopyValue(dynamicStoreRef, servicePath);
CFRelease(servicePath);
}
if (propList) {
result = (CFArrayRef)CFDictionaryGetValue(propList, CFSTR("ServerAddresses"));
if (result) {
CFRetain(result);
}
CFRelease(propList);
}
CFRelease(dynamicStoreRef);
return result;
}