What is needed
Using scutil
, I may get the list of Network services, including from virtual interfaces (e.g. VPN).
scutil
> list
Which provides:
...
subKey [82] = State:/Network/Service/3EEEA1D1-D35B-427E-BDE0-2025141B495C
subKey [83] = State:/Network/Service/3EEEA1D1-D35B-427E-BDE0-2025141B495C/IPv6
subKey [84] = State:/Network/Service/7B9ECA06-5F37-474A-88A9-CC4EE3638A0E/DHCP
subKey [85] = State:/Network/Service/7B9ECA06-5F37-474A-88A9-CC4EE3638A0E/DNS
subKey [86] = State:/Network/Service/7B9ECA06-5F37-474A-88A9-CC4EE3638A0E/IPv4
subKey [87] = State:/Network/Service/D987D3B3-5AF0-43C8-937E-86B0F8B9D59A
subKey [88] = State:/Network/Service/D987D3B3-5AF0-43C8-937E-86B0F8B9D59A/IPv6
subKey [89] = State:/Network/Service/com.sparklabs.Viscosity.utun10/DNS
subKey [90] = State:/Network/Service/com.sparklabs.Viscosity.utun10/IPv4
subKey [91] = State:/Network/Service/com.sparklabs.Viscosity.utun10/IPv6
You may see that first 82-88 are real interfaces, while the last 89-91 is a virtual interface (UTUN) which corresponds to a VPN of type OpenVPN. I need to retrieve this com.sparklabs.Viscosity.utun10
service name.
Getting services
Failing to get services of virtual interfaces
I am able to list all physical services with the following code:
auto prefs = SCPreferencesCreate(nullptr, CFSTR("test"), nullptr);
CFArrayRef services = SCNetworkServiceCopyAll(prefs);
const size_t num = CFArrayGetCount(services);
for (size_t i = 0; i< num; ++i)
{
NSLog(@"Service: %@", CFArrayGetValueAtIndex(services, i));
}
However the result does not include the UTUN
service:
Service: <SCNetworkService 0x7fa2387078b0 [0x7fff84d43cf0]> {id = FDE22A30-76DA-4AE4-963F-FDE4769EAC91, prefs = 0x7fa23840a900}
Service: <SCNetworkService 0x7fa238706430 [0x7fff84d43cf0]> {id = 9EFF9EEA-EE7B-4D85-8DBD-291FA1A80FE5, prefs = 0x7fa23840a900}
Service: <SCNetworkService 0x7fa238706910 [0x7fff84d43cf0]> {id = 3BA8DFA7-C609-4746-A5B5-5A452F6AF44B, prefs = 0x7fa23840a900}
Service: <SCNetworkService 0x7fa238706140 [0x7fff84d43cf0]> {id = 7B9ECA06-5F37-474A-88A9-CC4EE3638A0E, prefs = 0x7fa23840a900}
Service: <SCNetworkService 0x7fa238705de0 [0x7fff84d43cf0]> {id = A14CD980-C388-4A5D-8DE5-493B62D78A60, prefs = 0x7fa23840a900}
Getting interfaces
Failing to get the service related to the interface
Interfaces, including virtual one are quite easy to retrieve:
SCDynamicStoreRef ds = SCDynamicStoreCreate(nullptr, CFSTR("test"), nullptr, nullptr);
const auto list = SCDynamicStoreCopyKeyList(ds, CFSTR("State:/Network/Interface"));
const size_t num = CFArrayGetCount(list);
for (size_t i = 0; i< num; ++i)
{
auto key = static_cast<CFStringRef>(CFArrayGetValueAtIndex(list, i));
auto value = static_cast<CFDictionaryRef>(SCDynamicStoreCopyValue(ds, key));
NSLog(@"%@ = %@", key, value);
}
With the following result:
State:/Network/Interface = {
Interfaces = (
...
en0,
en1,
...
utun10
);
}
However, I am not able to get the service interface related to them, thus.
Question
How to list virtual network services?