2

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?

How to list all available patterns in a SCDynamicStorage?

Finding DNS server settings programmatically on Mac OS X

Adrian Maire
  • 14,354
  • 9
  • 45
  • 85

0 Answers0