1

我正在尝试从沙盒应用程序中检测 macOS 中的 VPN 连接是否处于活动状态,但很难找到适用于各种 VPN 服务的通用解决方案。目前,我正在使用 2 种方法(见下文),但这些方法似乎对所有 VPN 服务/客户端都不可靠。

以下方法适用于 Cisco AnyConnect 客户端和我的 VPN 服务,但对于其他 VPN 客户端/服务,例如 Viscosity(可能还有其他 OpenVPN 客户端),这些方法根本不起作用。在比较从非活动-VPN-connection 到活动-VPN-connection 的值时,在 DNS 服务器或主要服务值中未检测到任何更改。

我还应该提到我已经看过这篇文章,并且认为这不是这个特定用例的好解决方案。我不想假设对于每一个 VPN 服务来说,它总是一个只有在 VPN 连接处于活动状态时才可用的主机。

任何指导将不胜感激。先感谢您。

1)查看当前的 DNS 服务器(取自此处

- (NSString *)getDNSAddressesCSV
{
    NSMutableArray *addresses = [NSMutableArray new];

    union res_sockaddr_union servers[NI_MAXSERV];

    int serversFound = res_9_getservers(_state, servers, NI_MAXSERV);

    char hostBuffer[NI_MAXHOST];

    for (int i = 0; i < serversFound; i ++)
    {
        union res_sockaddr_union s = servers[i];

        if (s.sin.sin_len > 0)
        {
            if (EXIT_SUCCESS == getnameinfo((struct sockaddr *)&s.sin,  // Pointer to your struct sockaddr
                                            (socklen_t)s.sin.sin_len,   // Size of this struct
                                            (char *)&hostBuffer,        // Pointer to hostname string
                                            sizeof(hostBuffer),         // Size of this string
                                            nil,                        // Pointer to service name string
                                            0,
                                            NI_NUMERICHOST))
            {          // Flags given
                [addresses addObject:[NSString stringWithUTF8String:hostBuffer]];
            }
        }
    }

    return [addresses componentsJoinedByString:@","];
}



和 2) 从SCDynamicStore 获取当前的主要服务(取自这里

- (NSString *) getVPNService
{
    SCDynamicStoreRef dynamicStoreDomainState = SCDynamicStoreCreate(NULL,
                                                                     CFSTR("appNameGoesHere"),
                                                                     NULL,
                                                                     NULL);
    if (dynamicStoreDomainState)
    {
        NSString *netIPv4Key = [NSString stringWithFormat:@"%@/%@/%@/%@",
                                kSCDynamicStoreDomainState,
                                kSCCompNetwork,
                                kSCCompGlobal,
                                kSCEntNetIPv4];

        NSMutableDictionary *netIPv4Dictionary = (NSMutableDictionary *) CFBridgingRelease(SCDynamicStoreCopyValue(dynamicStoreDomainState, (CFStringRef)netIPv4Key));

        if (netIPv4Dictionary )
        {
            NSString *primaryService = [netIPv4Dictionary objectForKey:(NSString *)kSCDynamicStorePropNetPrimaryService];

            if (primaryService)
            {
                CFRelease(dynamicStoreDomainState);
                CFRelease((__bridge CFTypeRef)(netIPv4Key));
                return primaryService;
            }
            else
            {
                CFRelease(dynamicStoreDomainState);
                CFRelease((__bridge CFTypeRef)(netIPv4Key));
                return @"";
            }
        }

        CFRelease(dynamicStoreDomainState);
    }

    return @"";
}
4

1 回答 1

0

从谷歌看这里:https ://forums.developer.apple.com/thread/113491

苹果员工表示不存在这样的公共 API。

同样来自谷歌,请看这里:https ://superuser.com/questions/577094/how-can-i-tell-if-os-x-is-connected-to-a-vpn-network-from-the-command -线

最后一个 Apple Script 解决方案可能会让您感兴趣

于 2019-02-15T01:40:28.077 回答