Skip to content

Instantly share code, notes, and snippets.

@Haraguroicha
Created April 27, 2016 08:58
Show Gist options
  • Save Haraguroicha/0b225876d58949002fdd8e8553b6e348 to your computer and use it in GitHub Desktop.
Save Haraguroicha/0b225876d58949002fdd8e8553b6e348 to your computer and use it in GitHub Desktop.
Get WiFi Info from private api
@import SystemConfiguration;
#import <dlfcn.h>
#import <mach/port.h>
#import <mach/kern_return.h>
#include <sys/socket.h>
#include <sys/sysctl.h>
#include <net/if.h>
#include <net/if_dl.h>
#include <ifaddrs.h>
#include <arpa/inet.h>
@implementation UIDevice (detailInformation)
- (NSDictionary *)getWiFiInfo {
NSMutableDictionary *wifiInfo = [NSMutableDictionary new];
// base path: Root>J86AP>AppleARMPE>arm-io>AppleS5L8960XIO>usb-complex>AppleS5L8960XUSBArbitrator>usb-ehci1>AppleS5L8960XUSBEHCI>wlan>AppleBCMWLANBusInterfaceHSIC>AppleBCMWLANCore
// to get wifi lqm
// . :LinkQualityMetrics
// to get wifi ssid and bssid
// . > en0:IO80211(B)?SSID
void *IOKit = dlopen("/System/Library/Frameworks/IOKit.framework/IOKit", RTLD_NOW);
NSMutableDictionary *io80211 = nil;
if (IOKit) {
mach_port_t *kIOMasterPortDefault = dlsym(IOKit, "kIOMasterPortDefault");
CFMutableDictionaryRef (*IOServiceMatching)(const char *name) = dlsym(IOKit, "IOServiceMatching");
mach_port_t (*IOServiceGetMatchingService)(mach_port_t masterPort, CFDictionaryRef matching) = dlsym(IOKit, "IOServiceGetMatchingService");
CFTypeRef (*IORegistryEntryCreateCFProperty)(mach_port_t entry, CFStringRef key, CFAllocatorRef allocator, uint32_t options) = dlsym(IOKit, "IORegistryEntryCreateCFProperty");
kern_return_t (*IORegistryEntryCreateCFProperties)(mach_port_t entry, CFMutableDictionaryRef *properties, CFAllocatorRef allocator, uint32_t options) = dlsym(IOKit, "IORegistryEntryCreateCFProperties");
kern_return_t (*IORegistryEntryGetChildIterator)(mach_port_t entry, const char plane[128], mach_port_t *iterator) = dlsym(IOKit, "IORegistryEntryGetChildIterator");
kern_return_t (*IOIteratorNext)(kern_return_t iterator) = dlsym(IOKit, "IOIteratorNext");
kern_return_t (*IORegistryEntryGetNameInPlane)(mach_port_t entry, const char plane[128], char name[128]) = dlsym(IOKit, "IORegistryEntryGetNameInPlane");
kern_return_t (*IOObjectRelease)(mach_port_t object) = dlsym(IOKit, "IOObjectRelease");
if (kIOMasterPortDefault && IOServiceGetMatchingService && IORegistryEntryCreateCFProperty && IOObjectRelease) {
mach_port_t BCMWLANDevice = IOServiceGetMatchingService(*kIOMasterPortDefault, IOServiceMatching("AppleBCMWLANCore"));
if (BCMWLANDevice) {
CFMutableDictionaryRef properties = 0;
kern_return_t IO80211 = KERN_SUCCESS;
IO80211 = IORegistryEntryCreateCFProperties(BCMWLANDevice, &properties, kCFAllocatorDefault, 0);
if (CFGetTypeID(properties) == CFDictionaryGetTypeID()) {
io80211 = [NSMutableDictionary dictionaryWithDictionary:(__bridge NSDictionary *)properties];
CFRelease(properties);
}
IOObjectRelease(IO80211);
kern_return_t status = KERN_SUCCESS;
mach_port_t children = 0;
status = IORegistryEntryGetChildIterator(BCMWLANDevice, "IOService", &children);
mach_port_t child = 0;
mach_port_t childUpNext = 0;
if (status == KERN_SUCCESS) {
childUpNext = IOIteratorNext(children);
while (childUpNext) {
child = childUpNext;
childUpNext = IOIteratorNext(children);
CFMutableDictionaryRef _properties = 0;
kern_return_t _IO80211 = KERN_SUCCESS;
_IO80211 = IORegistryEntryCreateCFProperties(child, &_properties, kCFAllocatorDefault, 0);
char title[128];
IORegistryEntryGetNameInPlane(child, "IOService", title);
if (CFGetTypeID(_properties) == CFDictionaryGetTypeID()) {
NSDictionary *value = [NSDictionary dictionaryWithDictionary:(__bridge NSDictionary *)_properties];
CFRelease(_properties);
[io80211 setValue:value
forKey:[NSString stringWithCString:title
encoding:NSUTF8StringEncoding]];
}
IOObjectRelease(_IO80211);
IOObjectRelease(child);
}
IOObjectRelease(children);
}
IOObjectRelease(BCMWLANDevice);
}
}
dlclose(IOKit);
}
IOKit = nil;
if (io80211 != nil) {
NSArray *linkQualityMetrics = [[io80211 objectForKey:@"LinkQualityMetrics"] componentsSeparatedByString:@" "];
for (NSString *linkQualityMetric in linkQualityMetrics) {
if ([linkQualityMetric containsString:@"="]) {
NSArray *lqm = [linkQualityMetric componentsSeparatedByString:@"="];
[wifiInfo setValue:[lqm objectAtIndex:1]
forKey:[lqm objectAtIndex:0]];
}
}
NSDictionary *en0 = [io80211 objectForKey:@"en0"];
NSData *BSSIDData = [en0 objectForKey:@"IO80211BSSID"];
const unsigned char *buffer = [BSSIDData bytes];
NSMutableString *BSSID = [NSMutableString stringWithCapacity:[BSSIDData length] * 2];
for (NSInteger i = 0; i < [BSSIDData length]; i++) {
[BSSID appendFormat:@"%02lX", (unsigned long)buffer[i]];
}
BSSID = (NSMutableString *)[BSSID regexReplace:@"(\\w{2})(\\w{2})(\\w{2})(\\w{2})(\\w{2})(\\w{2})" WithTemplate:@"$1:$2:$3:$4:$5:$6"];
[wifiInfo setValue:[en0 objectForKey:@"IO80211SSID"] forKey:@"SSID"];
[wifiInfo setValue:[NSString stringWithString:BSSID] forKey:@"BSSID"];
[wifiInfo setValue:[en0 objectForKey:@"IO80211Band"] forKey:@"Band"];
[wifiInfo setValue:[en0 objectForKey:@"IO80211Channel"] forKey:@"Channel"];
// following only support on iOS 9 and above
[wifiInfo setValue:[en0 objectForKey:@"IO80211ChannelBandwidth"] forKey:@"ChannelBandwidth"];
[wifiInfo setValue:[en0 objectForKey:@"IO80211ChannelFrequency"] forKey:@"ChannelFrequency"];
}
return [[NSDictionary alloc] initWithDictionary:wifiInfo];
}
@end
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment