#include <sys/types.h>
#include <sys/param.h>
#include <sys/stat.h>
#include <dlfcn.h>
#include <SystemConfiguration/CaptiveNetwork.h>
#pragma mark -
#pragma mark CaptiveNetwork.framework APIs (exported through the SystemConfiguration.framework)
#if TARGET_OS_IPHONE
const CFStringRef kCNNetworkInfoKeySSIDData = CFSTR("SSIDDATA");
const CFStringRef kCNNetworkInfoKeySSID = CFSTR("SSID");
const CFStringRef kCNNetworkInfoKeyBSSID = CFSTR("BSSID");
#endif // TARGET_OS_IPHONE
static void *
__loadCaptiveNetwork(void) {
static void *image = NULL;
if (NULL == image) {
const char *framework = "/System/Library/PrivateFrameworks/CaptiveNetwork.framework/CaptiveNetwork";
struct stat statbuf;
const char *suffix = getenv("DYLD_IMAGE_SUFFIX");
char path[MAXPATHLEN];
strlcpy(path, framework, sizeof(path));
if (suffix) strlcat(path, suffix, sizeof(path));
if (0 <= stat(path, &statbuf)) {
image = dlopen(path, RTLD_LAZY | RTLD_LOCAL);
} else {
image = dlopen(framework, RTLD_LAZY | RTLD_LOCAL);
}
}
return (void *)image;
}
Boolean
CNSetSupportedSSIDs(CFArrayRef ssidArray)
{
static typeof (CNSetSupportedSSIDs) *dyfunc = NULL;
if (!dyfunc) {
void *image = __loadCaptiveNetwork();
if (image) dyfunc = dlsym(image, "__CNSetSupportedSSIDs");
}
return dyfunc ? dyfunc(ssidArray) : FALSE;
}
Boolean
CNMarkPortalOnline(CFStringRef interfaceName)
{
static typeof (CNMarkPortalOnline) *dyfunc = NULL;
if (!dyfunc) {
void *image = __loadCaptiveNetwork();
if (image) dyfunc = dlsym(image, "__CNMarkPortalOnline");
}
return dyfunc ? dyfunc(interfaceName) : FALSE;
}
Boolean
CNMarkPortalOffline(CFStringRef interfaceName)
{
static typeof (CNMarkPortalOffline) *dyfunc = NULL;
if (!dyfunc) {
void *image = __loadCaptiveNetwork();
if (image) dyfunc = dlsym(image, "__CNMarkPortalOffline");
}
return dyfunc ? dyfunc(interfaceName) : FALSE;
}
CFArrayRef
CNCopySupportedInterfaces(void)
{
static typeof (CNCopySupportedInterfaces) *dyfunc = NULL;
if (!dyfunc) {
void *image = __loadCaptiveNetwork();
if (image) dyfunc = dlsym(image, "__CNCopySupportedInterfaces");
}
return dyfunc ? dyfunc() : NULL;
}
#if TARGET_OS_IPHONE
CFDictionaryRef
CNCopyCurrentNetworkInfo(CFStringRef interfaceName)
{
static typeof (CNCopyCurrentNetworkInfo) *dyfunc = NULL;
if (!dyfunc) {
void *image = __loadCaptiveNetwork();
if (image) dyfunc = dlsym(image, "__CNCopyCurrentNetworkInfo");
}
return dyfunc ? dyfunc(interfaceName) : NULL;
}
#endif // TARGET_OS_IPHONE