Getting the Airport Name and MAC Address
Two years down the line, I rewrote this code to be cleaner and better. You probably want to check out that blog entry instead.
Context
I’m working on a rewrite of WiLMa and have been going through some of my older code from when I was just learning to write Mac applications. One of the more challenging things I had to do with WiLMa was to get the name and MAC address of the network my computer was connected to.
I’ve put it together into a little class and am posting it here in hopes that I can save somebody else some trouble down the line. In the beginning, sample code was always more helpful to me than API documents and the code I post in this blog is my way of giving a little back.
To emphasize, this gets the MAC address and SSID of the router that your Mac is connected to. It does not get your own computers MAC address.
Code – The Routers MAC Address
This next bit of code retrieves the IP address of the current router from the dynamic store, and then uses an NSTask to call /usr/sbin/arp to get the routers MAC address. This has always struck me as a convoluted solution but I haven’t been able to find anything better. If you know any better way, please email me. You’ll get mention in the about box if I use your solution.
NSMutableString *MACAddress = [NSMutableString string];
// Retrieves the IP Address of the router we’re connected to from the Dynamic Store
// Use ’scutil’ to browse the dynamic store from Terminal
SCDynamicStoreRef theDynamicStore = SCDynamicStoreCreate(nil, CFSTR("FindCurrentInterfaceAndIP"), nil, nil);
CFDictionaryRef returnedPList = SCDynamicStoreCopyValue(theDynamicStore, CFSTR("State:/Network/Global/IPv4"));
CFRelease(theDynamicStore);
if ([(NSDictionary *)returnedPList valueForKey:@"Router"] != nil) { // We’re attached to a network
// Find the MAC address of the router
// We’ll use /usr/sbin/arp to get the information we want
NSTask *arpTask = [[[NSTask alloc] init] autorelease];
NSPipe *newPipe = [NSPipe pipe];
NSFileHandle *readHandle = [newPipe fileHandleForReading];
[arpTask setStandardOutput:newPipe];
[arpTask setLaunchPath:@"/usr/sbin/arp"];
[arpTask setArguments:[NSArray arrayWithObject:[(NSDictionary *)returnedPList valueForKey:@"Router"]]];
[arpTask launch];
[arpTask waitUntilExit];
NSString *outputString = [[[NSString alloc] initWithData:[readHandle availableData] encoding:NSUTF8StringEncoding] autorelease];
// The outputString variable contains something like this:
// ? (192.168.1.1) at 0:18:f8:fb:ff:a7 on en1 [ethernet]
// We count spaces to extract the word we want
int i=0;
int spaceCount = 0;
for (i=0; i<[outputString length]; i++) {
if ([outputString characterAtIndex:i] == ‘ ‘) {
spaceCount++;
};
if (spaceCount == 3 && [outputString characterAtIndex:i] != ‘ ‘) {
[MACAddress appendFormat:@"%c",[outputString characterAtIndex:i]];
};
};
};
return MACAddress;
}
Code – The Routers SSID
Luckily we can retrieve the SSID from the dynamic store directly. This next snippet of code check if we’re using the ethernet interface, and return “Wired Network” if we are, and the SSID if we aren’t.
NSMutableString *interfaceName = [NSMutableString string];
// Figure out which interface we’re using
SCDynamicStoreRef theDynamicStore = SCDynamicStoreCreate(nil, CFSTR("FindCurrentInterfaceAndIP"), nil, nil);
CFDictionaryRef returnedPList = SCDynamicStoreCopyValue(theDynamicStore, CFSTR("State:/Network/Global/IPv4"));
if ([[(NSDictionary *)returnedPList valueForKey:@"PrimaryInterface"] isEqualTo:@"en0"]) { // On the wired interface
[interfaceName setString:@"Wired Network"];
} else { // On airport
CFDictionaryRef airportPlist = SCDynamicStoreCopyValue(theDynamicStore, CFSTR("State:/Network/Interface/en1/AirPort"));
[interfaceName setString:[(NSDictionary *)airportPlist valueForKey:@"SSID"]];
};
CFRelease(theDynamicStore);
return interfaceName;
}
That’s all for today folks. As always, all source is released free of charge. You may incorporate it into any of your applications. I assume no liability for any action that may come from you using this source. If you do use this in your application, I’d like a mention in your about box, but I don’t require it.