1/* 2 This file is part of Kismet 3 4 Kismet is free software; you can redistribute it and/or modify 5 it under the terms of the GNU General Public License as published by 6 the Free Software Foundation; either version 2 of the License, or 7 (at your option) any later version. 8 9 Kismet is distributed in the hope that it will be useful, 10 but WITHOUT ANY WARRANTY; without even the implied warranty of 11 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 GNU General Public License for more details. 13 14 You should have received a copy of the GNU General Public License 15 along with Kismet; if not, write to the Free Software 16 Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 17*/ 18 19 20#define __IN_OBJC_FILE__ 21 22#include "config.h" 23 24#ifdef SYS_DARWIN 25 26// Is this a bad idea, to try to merge obj-c and c++ code into one codebase? 27// Yes, probably. 28// Code derived from kismac by KF 29 30#import <Foundation/Foundation.h> 31#include <unistd.h> 32#include <sys/types.h> 33#include <sys/stat.h> 34#include <errno.h> 35#include "apple80211.h" 36#include <Carbon/Carbon.h> 37#include "darwin_control_wrapper.h" 38#import "darwin_wificontrol.h" 39 40 41int darwin_bcom_testmonitor() 42{ 43 NSDictionary *dict; 44 NSData *fileData; 45 NSString *error; 46 NSAutoreleasePool *pool; 47 pool = [[NSAutoreleasePool alloc] init]; 48 49 fileData = [NSData dataWithContentsOfFile:@"/System/Library/PrivateFrameworks/AppleTV.framework/Versions/Current/Resources/Info.plist"]; 50 dict = [NSPropertyListSerialization propertyListFromData:fileData mutabilityOption:kCFPropertyListImmutable format:NULL errorDescription:&error]; 51 if(!dict) 52 { 53 NSLog(@"%s", error); 54 } 55 else 56 { 57 if (strcmp([[dict valueForKeyPath:@"CFBundleExecutable"] cString], "AppleTV") == 0) return 1; 58 } 59 // This may work on AppleTV 1.1 also but I am not sure. This is a quick hack to force 1.0 to work. 60 fileData = [NSData dataWithContentsOfFile:@"/System/Library/MonitorPanels/AppleDisplay.monitorPanels/Contents/Resources/TVOptions.monitorPanel/Contents/Info.plist"]; 61 dict = [NSPropertyListSerialization propertyListFromData:fileData mutabilityOption:kCFPropertyListImmutable format:NULL errorDescription:&error]; 62 if(!dict) 63 { 64 NSLog(@"%s", error); 65 } 66 else 67 { 68 if (strcmp([[dict valueForKeyPath:@"CFBundleExecutable"] cString], "TVOptions") == 0) return 1; 69 } 70 fileData = [NSData dataWithContentsOfFile:@"/System/Library/Extensions/AppleAirPort2.kext/Contents/Info.plist"]; 71 dict = [NSPropertyListSerialization propertyListFromData:fileData mutabilityOption:kCFPropertyListImmutable format:NULL errorDescription:&error]; 72 if(!dict) 73 { 74 NSLog(@"%s", error); 75 } 76 else 77 { 78 79 if ([[dict valueForKeyPath:@"IOKitPersonalities.Broadcom PCI.APMonitorMode"] boolValue]) return 1; 80 } 81 fileData = [NSData dataWithContentsOfFile:@"/System/Library/Extensions/IO80211Family.kext/Contents/PlugIns/AppleAirPortBrcm4311.kext/Contents/Info.plist"]; 82 dict = [NSPropertyListSerialization propertyListFromData:fileData mutabilityOption:kCFPropertyListImmutable format:NULL errorDescription:&error]; 83 if(!dict) 84 { 85 NSLog(@"%s", error); 86 } 87 else 88 { 89 if ([[dict valueForKeyPath:@"IOKitPersonalities.Broadcom PCI.APMonitorMode"] boolValue]) return 1; 90 } 91 return -1; 92} 93 94int darwin_bcom_enablemonitorfile(const char *c_filename) 95{ 96 NSDictionary *dict; 97 NSData *data; 98 NSString *fileName; 99 NSAutoreleasePool *pool; 100 101 pool = [[NSAutoreleasePool alloc] init]; 102 fileName = [[NSString alloc] initWithCString:c_filename]; 103 104 if (chmod([fileName cString], 105 (S_IRUSR | S_IWUSR | S_IRGRP | S_IWGRP | S_IROTH | S_IWOTH)) < 0 && 106 errno != ENOENT) { 107 return -1; 108 } 109 110 data = [NSData dataWithContentsOfFile:fileName]; 111 if(!data) return 0; 112 dict = [NSPropertyListSerialization propertyListFromData:data mutabilityOption:kCFPropertyListMutableContainers format:NULL errorDescription:Nil]; 113 if(!dict) return 0; 114 [dict setValue:[NSNumber numberWithBool:true] forKeyPath:@"IOKitPersonalities.Broadcom PCI.APMonitorMode"]; 115 [[NSPropertyListSerialization dataFromPropertyList:dict format:kCFPropertyListXMLFormat_v1_0 errorDescription:nil] writeToFile:fileName atomically:NO]; 116 117 if (chmod([fileName cString], 118 (S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH)) < 0 && errno != ENOENT) { 119 return -1; 120 } 121 122 return 1; 123} 124 125int darwin_bcom_enablemonitor() 126{ 127 int ret, i; 128 NSAutoreleasePool *pool; 129 pool = [[NSAutoreleasePool alloc] init]; 130 char cmd[1024]; 131 132 ret = darwin_bcom_enablemonitorfile("/System/Library/Extensions/AppleAirPort2.kext/Contents/Info.plist") || 133 darwin_bcom_enablemonitorfile("/System/Library/Extensions/IO80211Family.kext/Contents/PlugIns/AppleAirPortBrcm4311.kext/Contents/Info.plist"); 134 135 if (ret == 0) { 136 return -1; 137 } 138 139 if (unlink("/System/Library/Extensions.kextcache") < 0 && errno != ENOENT) 140 return -1; 141 142 snprintf(cmd, 1024, "/usr/sbin/kextcache -k /System/Library/Extensions"); 143 if (system(cmd) != 0) 144 return -1; 145 146 if (unlink("/System/Library/Extensions.mkext") < 0 && errno != ENOENT) 147 return -1; 148 149 /* Throw a warning at the user and wait */ 150 fprintf(stderr, "ATTENTION: Kismet has enabled rfmon on your devices, however " 151 "to activate it, the kernel modules must be reloaded. There have " 152 "been reports of this causing a system crash. Kismet will wait 10 " 153 "seconds before attempting to reload the kernel modules. Press " 154 "control-c now to cancel reloading modules and reboot manually if " 155 "you do not want to proceed!\n\n"); 156 157 sleep(10); 158 159 /* we don't check the failure codes since we don't know which driver we're 160 * using... Also according to geordi we have to thrash the unload because 161 * sometimes it just refuses to unload the module. Highly inelegant. */ 162 for (i = 0; i < 10; i++) { 163 snprintf(cmd, 1024, "/sbin/kextunload -b com.apple.driver.AppleAirPort2" 164 ">/dev/null 2>/dev/null"); 165 system(cmd); 166 167 snprintf(cmd, 1024, "/sbin/kextunload -b " 168 "com.apple.driver.AppleAirPortBrcm4311 >/dev/null 2>/dev/null"); 169 system(cmd); 170 } 171 172 /* Try to reload them */ 173 snprintf(cmd, 1024, "/sbin/kextload /System/Library/Extensions/AppleAirPort2.kext" 174 ">/dev/null 2>/dev/null"); 175 system(cmd); 176 177 snprintf(cmd, 1024, "/sbin/kextload " 178 "/System/Library/Extensions/AppleAirPortBrcm4311.kext " 179 ">/dev/null 2>/dev/null"); 180 system(cmd); 181 182 fprintf(stderr, "ATTENTION: Completed trying to reload the kernel modules. " 183 "Sometimes this doesn't work, if Kismet does not start properly " 184 "you will need to manually reboot.\n"); 185 sleep(5); 186 187 return 1; 188} 189 190void *darwin_allocate_interface(const char *in_iface) { 191 DarwinWifi *darwin = [[DarwinWifi alloc] initWithInterface:[[NSString alloc] initWithUTF8String:in_iface]]; 192 193 return (void *) darwin; 194} 195 196void darwin_free_interface(void *in_darwin) { 197 // TODO 198} 199 200int darwin_set_channel(unsigned int in_channel, char *ret_err, void *in_darwin) { 201 DarwinWifi *darwin = (DarwinWifi *) in_darwin; 202 BOOL result; 203 NSError *err; 204 205 result = [darwin setChannel:in_channel error:ret_err]; 206 207 if (!result) { 208 return -1; 209 } 210 211 return 1; 212} 213 214int darwin_get_corewifi(void *in_darwin) { 215 DarwinWifi *darwin = (DarwinWifi *) in_darwin; 216 217 return [darwin getCoreWireless]; 218} 219 220void darwin_disassociate(void *in_darwin) { 221 DarwinWifi *darwin = (DarwinWifi *) in_darwin; 222 223 [darwin disAssociate]; 224} 225 226int darwin_get_channels(const char *in_iface, int **ret_channels) { 227 NSArray *supported; 228 int *ret = NULL; 229 int x = 0; 230 231 DarwinWifi *darwin = [[DarwinWifi alloc] initWithInterface:[[NSString alloc] initWithUTF8String:in_iface]]; 232 233 supported = [darwin getSupportedChannels]; 234 235 if (supported == nil) { 236 *ret_channels = NULL; 237 return 0; 238 } 239 240 ret = (int *) malloc(sizeof(int) * [supported count]); 241 242 for (id sup in supported) { 243 ret[x++] = [sup intValue]; 244 } 245 246 *ret_channels = ret; 247 248 x = [supported count]; 249 250 return x; 251} 252 253#endif 254 255