- 
      
- 
        Save wolever/4418079 to your computer and use it in GitHub Desktop. 
| #import <CoreWLAN/CoreWLAN.h> | |
| #import <objc/message.h> | |
| int main(int argc, char* argv[]) { | |
| @autoreleasepool { | |
| int ch; | |
| NSString *ssid = nil, *password = nil; | |
| while((ch = getopt(argc, argv, "s:p:h")) != -1) { | |
| switch(ch) { | |
| case 's': | |
| ssid = [NSString stringWithUTF8String:optarg]; | |
| break; | |
| case 'p': | |
| password = [NSString stringWithUTF8String:optarg]; | |
| break; | |
| case '?': | |
| case 'h': | |
| default: | |
| printf("USAGE: %s [-s ssid] [-p password] [-h] command\n", argv[0]); | |
| printf("\nOPTIONS:\n"); | |
| printf(" -s ssid SSID\n"); | |
| printf(" -p password WEP password\n"); | |
| printf(" -h Print help\n"); | |
| printf("\nCOMMAND:\n"); | |
| printf(" status Print interface mode\n"); | |
| printf(" start Start Host AP mode\n"); | |
| printf(" stop Stop Host AP mode\n"); | |
| return 0; | |
| } | |
| } | |
| NSString *command = nil; | |
| if(argv[optind]) { | |
| command = [NSString stringWithUTF8String:argv[optind]]; | |
| } | |
| CWInterface *iface = [CWInterface interface]; | |
| if(!command || [command isEqualToString:@"status"]) { | |
| NSString *mode = nil; | |
| switch(iface.interfaceMode) { | |
| case kCWInterfaceModeStation: | |
| mode = @"Station"; | |
| break; | |
| case kCWInterfaceModeIBSS: | |
| mode = @"IBSS"; | |
| break; | |
| case kCWInterfaceModeHostAP: | |
| mode = @"HostAP"; | |
| break; | |
| case kCWInterfaceModeNone: | |
| default: | |
| mode = @"None"; | |
| } | |
| printf("%s\n", [mode UTF8String]); | |
| } else if([command isEqualToString:@"stop"]) { | |
| // Stop Host AP mode | |
| if(getuid() != 0) { | |
| printf("this may need root (trying anyway)...\n"); | |
| } | |
| objc_msgSend(iface, @selector(stopHostAPMode)); | |
| } else if([command isEqualToString:@"start"]) { | |
| if(!ssid) { | |
| printf("error: an ssid must be specified\n"); | |
| return 1; | |
| } | |
| // known security types: | |
| // 2: no securiry | |
| // 16: wep | |
| // Note: values [-127..127] have been tried, and all but these return errors. | |
| int securityType = 2; | |
| if(password) { | |
| if([password length] < 10) { | |
| printf("error: password too short (must be >= 10 characters)\n"); | |
| return 1; | |
| } | |
| securityType = 16; | |
| } | |
| NSSet *chans = [iface supportedWLANChannels]; | |
| //printf("chan count: %lu\n", [chans count]); | |
| NSEnumerator *enumerator = [chans objectEnumerator]; | |
| CWChannel *channel; | |
| while ((channel = [enumerator nextObject])) { | |
| //printf("channel: %lu\n", [channel channelNumber]); | |
| if ([channel channelNumber] == 9) | |
| break; | |
| } | |
| // Start Host AP mode | |
| NSError *error = nil; | |
| objc_msgSend(iface, | |
| //@selector(startIBSSModeWithSSID:security:channel:password:error:), | |
| @selector(startHostAPModeWithSSID:securityType:channel:password:error:), | |
| //[@"hunter2" dataUsingEncoding:NSUTF8StringEncoding], | |
| [ssid dataUsingEncoding:NSUTF8StringEncoding], | |
| securityType, | |
| channel, | |
| //@"abc123ffff", | |
| password, | |
| &error); | |
| if(error) { | |
| printf("startHostAPModeWithSSID error: %s\n", [error.localizedDescription UTF8String]); | |
| return 1; | |
| } | |
| } | |
| return 0; | |
| } | |
| } | 
| all: hostap | |
| hostap: hostap.m | |
| clang -framework Foundation -framework CoreWLAN -o $@ $< | |
| clean: | |
| rm -rf hostap | 
| Copyright (C) 2012 Yoshimasa Niwa | |
| Permission is hereby granted, free of charge, to any person obtaining | |
| a copy of this software and associated documentation files (the | |
| "Software"), to deal in the Software without restriction, including | |
| without limitation the rights to use, copy, modify, merge, publish, | |
| distribute, sublicense, and/or sell copies of the Software, and to | |
| permit persons to whom the Software is furnished to do so, subject to | |
| the following conditions: | |
| The above copyright notice and this permission notice shall be | |
| included in all copies or substantial portions of the Software. | |
| THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, | |
| EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF | |
| MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND | |
| NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE | |
| LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION | |
| OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION | |
| WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. | 
It works in 10.10 for a couple of seconds. Drops connection then. It would be really appreciated if someone experienced can troubleshoot this because there is no option to create a secured WiFi network in Yosemite.
Here is a solution that works for 10.10: http://stackoverflow.com/questions/31342348/programmatically-create-ad-hoc-network-os-x
That's not a "solution" for 10.10, that creates an ad-hoc (IBSS) network with its huge limitations. This script, in contrast, used to create a full access point.
This seems to work partially on 10.14. Running sudo ./hostap -s MyNetworkName start successfully enters HostAP mode and creates the access point (you can see the Wi-Fi icon in the menu bar turn to the one with the up arrow). I can see the access point exists in the Wi-Fi menus of my iOS and Android devices, but when I attempt to join the on any device, the device stalls and does not join the network (on Android the Wi-Fi listing says "obtaining IP address" continuously and on iOS the Wi-Fi listing keeps showing the loading symbol). Is there any way around this issue?
Another error I run into: if I try to start HostAP mode with a password sudo ./hostap -s MyNetworkName -p 12345abcde start, I get the error:
startHostAPModeWithSSID error: The operation couldn’t be completed. (com.apple.wifi.apple80211API.error error -3900.)
Has anyone come across any solution to enter HostAP mode programmatically?
Have you tried this with 10.9 Mavericks? Doesn't seem to be working.
$ sudo ./hostap status
None
$ sudo ./hostap -s testssid start
startHostAPModeWithSSID error: Operation not permitted